求解联通子集个数等问题、
如:
并查集维护一个数组int pre[],记录前一个节点是什么
find()函数,查找一个集合的代表
int find(intx){
if(x==pre[x])
return x;
return find(pre[x]);
}
join(x,y)合并两个集合
void join (int x,int y){
x=find(x);
y=find(y);
if(x!=y){
pre[x]=y;
}
}
两种压缩方式:
1、优化压缩路径。缺点:只能在查找时才能进行路劲压缩
int find_pre(int x){
if(x==pre[x])
return x;
return pre[x]=find_pre(pre[x]);
}
2、带权合并。减少深度
rank[i],表示i节点的深度
void union(int x,int y){
x=find(x);
y=find(y);
if(x!=y){
if(rank[x]<rank[y])
pre[x]=y;
if(rank[x]==rank[y]
rank[x]++;
pre[y]=x;
}
}