Appearance
简介
并查集支持以下操作:
- 往一个集合中加入元素;
- 查询两个元素是否在同一集合;
- 合并两个集合。
问题
构造
把同集的两节点相连,则集合数
并查集在每个集合中选取一个「代表元素」作为根节点,构造树型结构。
如图,
根节点的
查询代表元素
集合的「代表元素」就是并查集中的根节点。若节点
时间复杂度为
cpp
// 返回节点 x 的根节点祖先
int find(int x) {
if (!fa[x])
return x;
return find(fa[x]);
}
查询是否同集
若两个节点所在树的根节点相同,则它们同集。
cpp
bool judge(int x, int y) {
return find(x) == find(y);
}
合并集合
若
将两集合根节点相连,即新建一条从
cpp
void merge(int x, int y) {
if (find(x) != find(y)) // 如果 x 和 y 已经同集,则不能再合并
fa[find(x)] = find(y);
}
路径压缩
- 每次查询出节点
所在集合的根节点 后,使 ; - 再次查询
的根节点时, find(i)
函数就会直接返回,免去递归过程。
时间复杂度优化为
cpp
int find(int x) {
if (!fa[x])
return x;
return fa[x] = find(fa[x]); // 返回时保存
}