转载保存c++并查集的思路和代码
// 注意:使用该代码,并不能使得所有的元素都直接指向根节点,仍然存在间接的指向
class UnionFind {
public:
vector<int> parent;
vector<int> size;
int n;
// 当前连通分量数目
int setCount;
public:
UnionFind(int _n): n(_n), setCount(_n), parent(_n), size(_n, 1) {
iota(parent.begin(), parent.end(), 0);
}
int findset(int x) {
return parent[x] == x ? x : parent[x] = findset(parent[x]);
}
bool unite(int x, int y) {
x = findset(x);
y = findset(y);
if (x == y) {
return false;
}
if (size[x] < size[y]) {
swap(x, y);
}
parent[y] = x;
size[x] += size[y];
--setCount;
return true;
}
bool connected(int x, int y) {
x = findset(x);
y = findset(y);
return x == y;
}
};
并查集的一些使用tips:
一般不把并查集使用得太复杂,内部结构如果过于复杂,也难以维护
只负责维护连通性
存在区间合并的题干,应当使用并查集
如果题干是拆分连通分量,反向思维,考虑逆向使用并查集