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:\n", ++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\n",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 }

 

你可能感兴趣的:(drag)