原理: 并查集,剪枝,加权
通用算法实现,以java为例
/**
* union-find算法(并查集算法)
*/
static class WeightedQuickUnionUF{
/**
* 总共有多少连通分支
*/
int count;
/**
* id[i]是i对应的父节点
*/
private int[] id;
/**
* sz[i]是i的权值,加权简化算法复杂度
*/
private int[] sz;
/**
* 初始化变量
* @param N 共有多少个独立个体
*/
public WeightedQuickUnionUF(int N){
//在没有union之前,count为N
count =N;
//在没有union之前,所有的父节点为自己
id = new int[N];
for(int i= 0; i < N;i++){
id[i] = i;
}
//在没有union之前,所有的权值都是1
sz = new int[N];
for(int j = 0;j < N; j++){
sz[j] = 1;
}
}
/**
* 查找根节点
* @param p 当前节点
* @return 根节点
*/
public int find(int p){
//一直往回找,同时压缩路径
while(p != id[p]){
id[p] = id[id[p]];
p = id[p];
}
return p;
}
/**
* 将两个不相连的节点相连
* @param p 一个节点
* @param q 一个节点
*/
public void union(int p,int q){
//找到根节点
int i = find(p);
int j = find(q);
//如果根节点相同
if(i == j){
return;
}else if(sz[i] < sz[j]){
//根据权值进行比较决定谁是父节点
id[i] = j;
sz[j]+=sz[i];
count--;
}else{
//根据权值进行比较决定谁是父节点
id[j] = i;
sz[i] += sz[j];
count--;
}
}
int count(){
return count;
}
}
}