并查集是判断元素是否有连接所属关系的数据结构,基本操作是查找父亲节点,判断是否相连,和合并操作,使用层数遍历和路径压缩的方法进行优化。
#include <cassert>
namespace UF2 {
class UnionFind {
private:
int* parent;
int count;
int* rank; // rank[i]表示以i为根集合的层数
public:
UnionFind(int count) {
parent = new int[count];
rank = new int[count];
this->count = count;
for (int i = 0; i < count; i++) {
parent[i] = i;
rank[i] = 1;
}
}
~UnionFind() {
delete[] parent;
delete[] rank;
}
int find(int p) {
assert(p >= 0 && p < count);
while (p != parent[p]) {
parent[p] = parent[parent[p]];
p = parent[p];
}
return p;
}
bool isConnected(int p, int q) {
return find(p) == find(q);
}
void unionElements(int p, int q) {
int pRoot = find(p);
int qRoot = find(q);
if (pRoot == qRoot)
return;
if (rank[pRoot] < rank[qRoot]) {
parent[pRoot] = qRoot;
}
else if (rank[qRoot] < rank[pRoot]) {
parent[qRoot] = pRoot;
}
else {
parent[pRoot] = qRoot;
rank[qRoot]++;
}
}
};
}