并查集
是一种树形数据结构,可用于 合并 和 查询
合并(Union):确定某个元素位于哪个子集
查询(Find):合并两个子集为一个集合
一、查找:
int find(int x) {
if(x == fa[x]) return x;
else return fa[x] = find(fa[x]);
}
二、合并:
void Union(int x, int y) {
x = find(x);
y = find(y);
fa[x] = y; // 把 x 所在集合合并到 y 所在集合上
}
三、按秩合并(又叫启发式合并)
即将小的集合合并到大的集合上减小合并代价
不使用启发式合并、只使用路径压缩的最坏时间复杂度是 O(m log n)
vector<int> size(N, 1); // 每棵子树的大小为 1
void Union(int x, int y) {
int xx = find(x), yy = find(y);
if(xx == yy) return ;
if(size[xx] > size[yy]) swap(xx, yy);
fa[xx] = yy; // 把小树连到大树的根上
size[yy] += size[xx];
}