(#每日一点点)day2-并查集
并查集(模板)
解决连通问题
完整代码
class UnionFind{
int[] parent;
int[] size;
int n;
//连通集合个数
int setCount;
//初始化
public UnionFind(int n){
this.n = n;
//一开始,每个节点的根节点都是自身
this.parent = new int[n];
for(int i = 0 ; i < n ; i++){
parent[i] = i;
}
//存放节点的秩的大小,初始值都为1
this.size = new int[n];
Arrays.fill(size,1);
this.setCount = n;
}
//查找根节点。
//路径压缩parent[x] = find(parent[x]),每一个连通集合中的分量都指向同一个根节点,避免形成链,降低查找速率
public int find(int x ){
return parent[x] == x ? x : (parent[x] = find(parent[x]));
}
//根据秩的大小连结分量:
public boolean unite(int x , int y){
//合并之前,先判断两个元素是否属于同一集合
int rootX = find(x);
int rootY = find(y);
if(rootX == rootY){
return false;
}
//秩比较大的分量作为根节点
if(size[rootX] > size[rootY]){
int temp = rootX;
rootX = rootY;
rootY = temp;
}
parent[rootX] = rootY;
size[rootX] += rootY;
--setCount;
return true;
}
//判断两个分量是否连通
public boolean isConnected(int x , int y){
return find(x) == find(y);
}
}