代码:
//4.2 并查集
struct DisjointSet {
vector<int>father, rank;
DisjointSet(int n) :father(n + 1), rank(n + 1) {
for (int i = 1; i <= n; ++i) {
father[i] = i;
}
}
int find(int v) {
return father[v] = (father[v] == v ? v : find(father[v]));
}
void merge(int x, int y) {
int a = find(x), b = find(y);
if (rank[a] < rank[b]) {
father[a] = b;
}
else {
father[b] = a;
if (rank[a] == rank[b]) {
++rank[a];
}
}
}
};
其他:
- 结点下标从1开始,从0开始要做适当修改
- 结点a,b属于同一连通分支,等价于find(a)==find(b),而不是father[a]==father[b]
- rank数组未必实际反映树高
- 附测试代码
#include<bits/stdc++.h> using namespace std; /**/ int main() { int n, m; scanf("%d%d", &n, &m); DisjointSet djs(n); printf("i=%d\n ", 0); for (int j = 1; j <= n; ++j) { printf("%d ", djs.father[j]); } for (int i = 1; i <= m; ++i) { int a, b; scanf("%d%d", &a, &b); djs.merge(a, b); printf("i=%d\n ",i); for (int j = 1; j <= n; ++j) { printf("%d ", djs.father[j]); } printf("\n"); } return 0; }