并查集
并查集(Disjoint Set)主要用于处理一些不相交集合的合并问题。经典的例子有连通子图、最小生成树Kruskal算法和最近公共祖先等。
应用背景例如:在一个城市中有n个人,他们分成不同的帮派;给出一些人的关系,问有多少个帮派,每人属于哪个帮派。
并查集:将编号分为1~n的n个对象划分为不相交集合,在每个集合中,选择其中某个元素代表所在集合。在这个集合中,并查集的操作有初始化、合并、查找
并查集操作的简单实现
初始化
//初始化
void init_set(){
for(int i=1;i<=maxn;i++){
F[i]=i;
siz[i]=0;
}
}
查找
//查找[路径压缩]
int Find(int x){
if(F[x]==x) return x;
return F[x]=Find(F[x]);
}
合并
合并时将元素少的集合合并到元素多的集合中,这样合并之后树的高度会相对较小。
//合并的优化
void Union_set(int x,int y){
if((x=Find(x))==(y=Find(y))) return;
else if(siz[x]<siz[y]) F[x]=y;
else if(siz[x]>siz[y]) F[y]=x;
else{
F[y]=x; siz[x]++;
}
}