在题目中,如果是求 对什么合并,或者是图的连通区域的个数之类的,应该考虑使用并查集
下面我总结出一个并查集的模板
package 图论.并查集;
import java.util.Arrays;
/**
* 并查集的实现
*/
public class UF_Tree {
/**
* 根据顶点创建一个数组
* 数组索引对应顶点 值对应他的父节点
*/
private int[] eleAndGroup;
//计算并查集中分组的个数
private int count;
/**
* 为了合并的时候 树数量小的去和合并到树数量大,从而使得树的整体高度 不会太大
* 所以记录下每个顶点作为根,树的顶点数量
*/
private int[] groupCount;
//初始化并查集
public UF_Tree(int N) {
eleAndGroup = new int[N];
//最开始每个顶点各自分成一组
for (int i = 0; i < N; i++) {
eleAndGroup[i] = i;
}
//最初的分组数量
count = N;
//最开始 每树的顶点数量都是1
groupCount = new int[N];
Arrays.fill(groupCount,1);
}
/**
* 查询顶点v处于哪个分组中
* @param v
* @return
*/
public int find(int v) {
//当找到一个 以自己作为分组,就说明找到了分组的父节点
while (eleAndGroup[v] != v) {
v = eleAndGroup[v];
}
return v;
}
/**
* 合并v所在的分组 和 u所在的分组
* @param v
* @param u
*/
public void union(int v,int u) {
//获取v u 所在分组的标识
int vRoot = find(v);
int uRoot = find(u);
//如果在同一个分组
if (vRoot == uRoot) {
return;
}
//将分组顶点数量小的和 合并到大的分组中
if (groupCount[vRoot] < groupCount[uRoot]) {
eleAndGroup[vRoot] = uRoot;
//更新uRoot 分组顶点的数量
groupCount[uRoot] += groupCount[vRoot];
}else {
eleAndGroup[uRoot] = vRoot;
//更新vRoot 分组顶点的数量
groupCount[vRoot] += groupCount[uRoot];
}
//分组数量-1
--count;
}
/**
* 获得分组的数量
* @return
*/
public int getCount() {
return count;
}
}