HDU 2818 Building Block【并查集+根节点偏移量】

大意:有30000个木块一次在一条线上排开  现在有两种操作  一种是把a木块所在的木块堆全部放到b木块堆的上面 

一种是 查询a木块底下有多少块

分析:并查集  偏移量代表相对于根节点的偏移量

一下为根方便建立   然后对于一个下根  用一个数组表示其最顶端的是什么  

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 const int maxn = 30005;
 7 
 8 int fa[maxn];
 9 int num[maxn];
10 int di[maxn];
11 
12 void init(int n) {
13     for(int i = 0; i <= n; i++) {
14         fa[i] = i;
15         num[i] = 0;
16         di[i] = i;
17     }
18 }
19 
20 int Find(int x) {
21     if(x == fa[x]) return fa[x];
22     int fax = fa[x];
23     fa[x] = Find(fa[x]);
24     num[x] = num[x] + num[fax];
25     return fa[x];
26 }
27 
28 int main() {
29     int n;
30     char a; int x, y;
31     while(EOF != scanf("%d",&n) ) {
32         init(30000);
33         while(n--) {
34             scanf("
%c",&a);
35             if(a == 'M') {
36                 scanf("%d %d",&x, &y);
37                 int xx = Find(x); int yy = Find(y);
38                 Find(di[xx]); Find(di[yy]);
39         //        printf("%d %d %d %d id = %d %d
", x, y, xx, yy, di[xx], di[yy]);
40                 if(xx != yy) {
41                     fa[xx] = yy;
42                     num[xx] = num[di[yy]] + 1;
43                     di[yy] = di[xx];
44                 }
45             } else {
46                 scanf("%d",&x);
47                 int z = Find(x);
48                 printf("%d
", num[x]);
49             }
50         }
51     }
52     return 0;
53 }
View Code

  有一点需要注意的是  每次更新完都要进行更新  要不可能会出现这次更新的不会对上次产生影响  也就是第38行

原文地址:https://www.cnblogs.com/zhanzhao/p/4363975.html