POJ1988--cube stacking(2007-04-18 17:01)

来源:互联网 发布:雅思词汇书哪本好 知乎 编辑:程序博客网 时间:2024/05/17 22:58
 

对并查集的扩展.看了下解题报告,总算有想法了.

sum[i]记录根结点i下面的结点数(包括自己)和up[i]记录在某结点i上面的结点数.则在一结点m之下的结点数为sum[findpar(m)]-up[m]-1   (findpar查找根结点)

在uni和findpar过程中更新sum和up的内容.(蓝色部分)

  1. #include "stdio.h"
  2. const int max_node=30005;
  3. int par[max_node+1];
  4. int up[max_node+1];
  5. int sum[max_node+1];
  6. int add;
  7. int findpar(int num){
  8.          int top;
  9.          if(par[num]!=num){
  10.                  top=findpar(par[num]);
  11.                 if(top!=par[num]){
  12.                          up[num]+=add;
  13.                  }
  14.                  add=up[num];
  15.                  par[num]=top;
  16.                  return top;
  17.          }
  18.          return num;
  19. }
  20. void uni(int a,int b){
  21.          a=findpar(a);
  22.          b=findpar(b);
  23.          par[b]=a;
  24.         up[b]=sum[a];
  25.          sum[a]+=sum[b];
  26. }
  27.         
  28. int main()
  29. {
  30. //         freopen("1.in","r",stdin);
  31.          int p;
  32.          scanf("%d",&p);
  33.          while(getchar()!='/n');
  34.          int s,d;
  35.          char c;
  36.          int i;
  37.          for(i=0;i< =max_node;++i){
  38.                  par[i]=i;
  39.                  up[i]=0;
  40.                  sum[i]=1;
  41.          }
  42.          while(p-->0){
  43.                  c=getchar();
  44.                  if(c=='M'){
  45.                          scanf("%d %d",&s,&d);
  46.                          while(getchar()!='/n');
  47.                          uni(s,d);
  48.                  }
  49.                  else{
  50.                          scanf("%d",&d);
  51.                          while(getchar()!='/n');
  52.                          printf("%d/n",sum[findpar(d)]-up[d]-1);
  53.                  }
  54.          }
  55.          return 0;
  56. }