一般并查集:
// 未改进版本
class Djset {
public:
vector<int> parent; // 记录节点的根
Djset(int n): parent(vector<int>(n)) {
for (int i = 0; i < n; i++) parent[i] = i;
}
int find(int x) {
if (x != parent[x]) return find(parent[x]);
return parent[x];
}
void merge(int x, int y) {
int rootx = find(x);
int rooty = find(y);
parent[rooty] = rootx;
}
};
优化后的并查集【按秩合并】【路径压缩】
// 注意:使用该代码,并不能使得所有的元素都直接指向根节点,仍然存在间接的指向
class Djset {
public:
vector<int> parent; // 记录节点的根
vector<int> rank; // 记录根节点的深度(用于优化)
Djset(int n): parent(vector<int>(n)), rank(vector<int>(n)) {
for (int i = 0; i < n; i++) {
parent[i] = i;
}
}
int find(int x) {
// 压缩方式:直接指向根节点
if (x != parent[x]) {
parent[x] = find(parent[x]);
}
return parent[x];
}
void merge(int x, int y) {
int rootx = find(x);
int rooty = find(y);
if (rootx != rooty) {
// 按秩合并
if (rank[rootx] < rank[rooty]) {
swap(rootx, rooty);
}
parent[rooty] = rootx;
if (rank[rootx] == rank[rooty]) rank[rootx] += 1;
}
}
};