initial:
void initial(int n) {for (int i = 0; i < n; i++) {p[i] = i;h[i] = 1;}
}
find:
int find(int x) {if (p[x] == x) return x;else return p[x] = find(p[x]);
}
union:
void union(int x, int y) {int rootx = find(x);int rooty = find(y);if (rootx != rooty) {if (h[rootx] < h[rooty]) p[rootx] = rooty;else if (h[rootx] > h[rooty]) p[rooty] = rootx;else p[rootx] = rooty, h[rooty]++;}
}
例题:
#include <iostream>
using namespace std;const int N = 10010;int p[N], h[N];
bool visited[N]; // 记录鸟是否出现过
bool isroot[N]; // 记录某个根节点是否已被计入树
int photos[10000][10]; // 每张照片中最多10只鸟,最多10000张照片
int photosize[10000]; // 每张照片的鸟的数量void initial(int n) {for (int i = 0; i < n; i++) {p[i] = i;h[i] = 1;visited[i] = false;isroot[i] = false;}
}int find(int x) {if (p[x] == x) return x;else return p[x] = find(p[x]);
}void unionset(int x, int y) {int rootx = find(x);int rooty = find(y);if (rootx != rooty) {if (h[rootx] < h[rooty]) p[rootx] = rooty;else if (h[rootx] > h[rooty]) p[rooty] = rootx;else p[rootx] = rooty, h[rooty]++;}
}int main() {int n;cin >> n;initial(N);int maxid = 0;// 输入照片数据for (int i = 0; i < n; i++) {int k;cin >> k;photosize[i] = k;for (int j = 0; j < k; j++) {int bird;cin >> bird;photos[i][j] = bird;visited[bird] = true;if (bird > maxid) maxid = bird;}}// 合并同一张照片的鸟for (int i = 0; i < n; i++) {int k = photosize[i];for (int j = 1; j < k; j++) {unionset(photos[i][0], photos[i][j]);}}int birdcnt = 0, treecnt = 0;// 统计鸟的数量和树的数量(去重根节点)for (int i = 1; i <= maxid; i++) {if (visited[i]) {birdcnt++;int root = find(i);if (!isroot[root]) {isroot[root] = true;treecnt++;}}}cout << treecnt << " " << birdcnt << endl;// 处理查询int q;cin >> q;while (q--) {int x, y;cin >> x >> y;if (find(x) == find(y)) cout << "Yes" << endl;else cout << "No" << endl;}return 0;
}