并查集 (disjoint set union) 是 最优美的数据结构之一
合并 (merge): 把两个集合合并
查找 (find): 查找一个元素的代表元素(并且在过程中压缩路径)
每个集合由一个代表元素(representative element)代表
我们使用并查集时,为了不让其形成链条图而加大时间复杂度,会用 路径压缩 让其变成菊花图
初始化:所有元素都是自己的代表
int fa[n+5]
for(int i=1;i<=n;i++){
fa=i;
}
并合:找到两个元素的代表元素,把其中一个的代表设成另一个
void merge(int a, int b){
int x=find(a), y=find(b);
fa[x] = fa[y];
}
查找:如果当前是代表元素返回,否则设当前元素的代表节点 (因此每个元素直接directly 连到代表元素)为之后查找的根结点再返回
int find(int x){
return fa[x] == x ? x : (fa[x]=find(fa[x]));
}
并合集延伸出来的操作:
查找两个元素是否在同一个集合里