并查集 -- 模板

并查集模板

 1   int p[MAXN];
 2   int r[MAXN];
 3   
 4   void init(int n) {
 5       for (int i = 1; i <= n; i++) {
 6           p[i] = i, r[i] = 0;
 7       }
 8   }
 9  
10  int find(int x) { return p[x] == x ? x : p[x] = find(p[x]); }
11  
12  bool same(int x, int y) { return find(x) == find(y); }
13  
14  void unite(int x, int y) {
15      x = find(x);
16      y = find(y);
17      if (x == y) return;
18      if (r[x] < r[y]) {
19          p[x] = y;
20     } else {
21          p[y] = x;
22          if (r[x] == r[y]) r[x]++;
23      }
24  }

例题:

带计数的并查集

题意:
在另一个宇宙,一个月有 N 天。多变的天气条件使得人们很恼火,终于,天气统计局产生了。它会对外发布 M 条信息,格式如下: X Y 表示第 X 天的天气和第 Y 天一样。

但民众并不满足于此,他们想知道有多少天的天气和第 X 天一样。 现在,作为一个聪明的程序员,你能帮他们解决这个问题吗?

题解:
给并查集加上计数功能

 1 #include<cstdio>
 2 using namespace std;
 3 int set[1000000], num[1000000];
 4 
 5 int findSet(int x) {
 6     if (x == set[x]) return x;
 7     else return set[x] = findSet(set[x]);
 8 }
 9 
10 void unionSet(int x, int y) {
11     int fx = findSet(x);
12     int fy = findSet(y);
13     if (fx != fy) {
14         num[fy] += num[fx];
15         set[fx] = fy;
16     }
17 }
18 
19 int main() {
20     int n, m, q, x, y, id;
21     scanf("%d%d", &n, &m);
22     for (int i = 1; i <= n; i++) {
23         set[i] = i;
24         num[i] = 1;
25     }
26     for (int i = 0; i < m; i++) {
27         scanf("%d%d", &x, &y);
28         unionSet(x, y);
29     }
30     scanf("%d", &q);
31     while (q--) {
32         scanf("%d", &id);
33         printf("%d
", num[findSet(id)]);
34     }
35     return 0;
36 }
原文地址:https://www.cnblogs.com/romaLzhih/p/9489841.html