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

来源:互联网 发布:linux 系统日志 命令 编辑:程序博客网 时间:2024/04/28 05:07

大意:有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("\n%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\n", 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\n", num[x]);49             }50         }51     }52     return 0;53 }
View Code

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

0 0