hdu 3635 Dragon Balls 并查集

推荐题解:http://www.cppblog.com/cxiaojia/archive/2011/11/04/nyoj431.html

思路:看懂题意后就知道用并查集了。询问的前两个问题都很好解决,有点难度的是第三个问题,龙珠被移动的次数。我用rnk数组统计每颗龙珠移动的次数,路径压缩后,每颗龙珠的父亲就是它所在的城市,如果这颗龙珠所在的城市所有的龙珠被移走的话,这座城市变成一座空城市,所以不会有龙珠再被移动到这座城市,就是说一座城市只能转移一次,假设a所在的城市的所有龙珠移动到了b,合并的时候统计这座城市移动的次数,那么统计龙珠的时候,只要统计它的父亲它的祖父一直到它的老祖,每个长辈的rnk和就是这颗龙珠的移动次数。所以在merge的时候让它父亲的rnk++,Find的时候让它遍历到根节点每次都加上一个长辈的rnk。写完后会感觉到,就是一个体的并查集。


注意:printf的先从右向左计算  再输出,右边的数受左边的数影响时容易出错。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<string>
 6 #include<queue>
 7 #include<algorithm>
 8 #include<map>
 9 #include<iomanip>
10 #include<climits>
11 #define INF 1e11
12 #define MAXN 10010 
13 using namespace std;
14 
15 #define _min(a,b) (((a)<(b))?((a):(b)))
16 //适用于正负整数
17 template <class T>
18 inline bool scan_d(T &ret) {
19     char c; int sgn;
20     if (c = getchar(), c == EOF) return 0; //EOF
21     while (c != '-' && (c<'0' || c>'9')) c = getchar();
22     sgn = (c == '-') ? -1 : 1;
23     ret = (c == '-') ? 0 : (c - '0');
24     while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
25     ret *= sgn;
26     return 1;
27 }
28 
29 int ball_num[MAXN];
30 int fa[MAXN];
31 int rnk[MAXN];
32 int a, b;
33 int T, n, m, k;
34 char ch;
35 
36 int find(int x) {
37     if (fa[x] == x) return x;
38     int t = fa[x];
39     fa[x] = find(fa[x]);
40     rnk[x] += rnk[t];
41     return fa[x];
42 }
43 
44 void init(int n)
45 {
46     for (int i = 1; i <= n; ++i) {
47         ball_num[i] = 1;
48         fa[i] = i;
49         rnk[i] = 0;
50     }
51 }
52 
53 bool merge(int a, int b)
54 {
55     int x = find(a);
56     int y = find(b);
57     if (x == y) return false;
58     else {
59         ball_num[y] += ball_num[x];
60         ball_num[x] = 0;
61         fa[x] = fa[y];
62         rnk[x] = 1;
63     }
64     return true;
65 }
66 
67 void process()
68 {
69     printf("Case %d:
", ++k);
70     scan_d(n); scan_d(m);
71     init(n);
72     for (int i = 0; i < m; ++i) {
73         cin >> ch;
74         if (ch == 'T') {
75             scan_d(a); scan_d(b);
76             merge(a, b);
77         }
78         else {
79             scan_d(a);
80             b = find(a);
81             printf("%d %d %d
",b, ball_num[b], rnk[a]);
82         }
83     }
84 }
85 
86 int main()
87 {
88     scan_d(T);
89     while (T--)
90         process();
91     //system("pause");
92     return 0;
93 }
原文地址:https://www.cnblogs.com/usedrosee/p/4250974.html