并查集是维护集合的数据结构,主要用于解决一些元素分组的问题。并查集支持以下两个操作:
- 合并:合并两个不相交的集合;
- 查找:判断两个元素是否在一个集合。
父亲结点的定义
int fa[1000006];
初始化
初始时每个元素都是一个独立的集合。
代码中n
为元素数目。
void init(int n){
for(int i=1;i<=n;i+=1)
fa[i]=i;
}
查找
查找元素x
的根结点。
迭代法
int find(int x){
while (x!=fa[x])
x=fa[x];
return x;
}
递归法
int find(int x){
if(x==fa[x])
return x;
return find(fa[x]);
}
路径压缩
在查找后,将路径上元素的父亲结点全部修改为根结点。
int find(int x){
int t=x;
while (x!=fa[x])
x=fa[x];
while (t!=fa[t]){
int tmp=t;
t=fa[t];
fa[tmp]=x;
}
return x;
}
合并
合并含元素x
与元素y
两个集合。
void joint(int x,int y){
fa[find(x)]=find(y);
}
完整代码:
#include<stdio.h>
int fa[1000006];
void init(int n){
for(int i=1;i<=n;i+=1)
fa[i]=i;
}
int find(int x){
int t=x;
while (x!=fa[x])
x=fa[x];
while (t!=fa[t]){
int tmp=t;
t=fa[t];
fa[tmp]=x;
}
return x;
}
void joint(int x,int y){
fa[find(x)]=find(y);
}