并查集模板
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 }