1 int par[MAX_N];//每个节点的父节点
2 int rank[MAX_N];//树的高度
3 //初始化n个元素
4 void init(int n) {
5 for (int i = 0; i < n; i++) {
6 par[i] = i;//初始时每个节点自成一树
7 rank[i] = 0;
8 }
9 }
10
11 //查询树的根
12 int find(int x) {
13 if (par[x] = x) {
14 return x;
15 }
16 else {
17 return par[x] = find(par[x]);//递归向上查询,查询到之后直接连到根
18 }
19 }
20
21 //合并x和y所属的集合
22 void unite(int x, int y) {
23 x = find(x);
24 y = find(y);
25 if (x == y)return;//xy已经在一组
26 if (rank[x] < rank[y]) { //x的高度小于y,则y作为新的根
27 par[x] = y;
28 }
29 else {
30 par[y] = x;
31 if (rank[x] == rank[y])rank[x]++;//若两树高度相同,则取x为新根,高度+1
32 }
33 }
34
35 //判断x和y是否属于同一集合
36 bool same(int x, int y) {
37 return find(x) == find(y);//根相同
38 }