hdu 3635 并查集

每个结点除了维护父亲结点编号以外,多维护一个sum值和r值,表示该子树的总结点数(如果该结点是根则sum值有效)以及它到根的距离(即被运输了几次),然后在路径压缩和集合合并的时候顺便维护这两个值即可。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 const int N = 10001;
 7 int f[N];
 8 int sum[N];
 9 int r[N];
10 
11 void init( int n )
12 {
13     for ( int i = 1; i <= n; i++ )
14     {
15         f[i] = i;
16         sum[i] = 1;
17         r[i] = 0;
18     }
19 }
20 
21 int findf( int x )
22 {
23     if ( f[x] == x ) return x;
24     int tx = findf(f[x]);
25     r[x] = r[x] + r[f[x]];
26     f[x] = tx;
27     return f[x];
28 }
29 
30 void union_set( int x, int y )
31 {
32     x = findf(x), y = findf(y);
33     if ( x == y ) return ;
34     f[x] = y;
35     sum[y] += sum[x];
36     r[x]++;
37 }
38 
39 int main ()
40 {
41     int t;
42     scanf("%d", &t);
43     for ( int _case = 1; _case <= t; _case++ )
44     {
45         printf("Case %d:\n", _case);
46         int n, m;
47         scanf("%d%d", &n, &m);
48         init(n);
49         while ( m-- )
50         {
51             char op[2];
52             int x, y;
53             scanf("%s", op);
54             if ( op[0] == 'T' )
55             {
56                 scanf("%d%d", &x, &y);
57                 union_set( x, y );
58             }
59             else
60             {
61                 scanf("%d", &x);
62                 int ans1 = findf(x);
63                 int ans2 = sum[ans1];
64                 int ans3 = r[x];
65                 printf("%d %d %d\n", ans1, ans2, ans3);
66             }
67         }
68     }
69     return 0;
70 }

 

posted @ 2015-08-09 09:13  hxy_has_been_used  阅读(125)  评论(0编辑  收藏  举报