poj1988Cube Stacking(并查集+路径压缩)


本题依然是并查集的应用,与上一个监狱的问题不同,本题计算的是距离,通过记录通往自己父节点距离的相对距离,与父节点到根节点(代表元素)的距离依次相加

路径压缩时每次都要更新节点。


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>

using namespace std;

const int maxn=30001;
int p;

struct
{
     int father,tot,dis;
}block[maxn];

void in()
{
     for(int i=0;i<maxn;++i)
     {
          block[i].dis=0;
          block[i].father=i;
          block[i].tot=1;
     }
}

int getanc(int a)
{

     if(block[a].father==a) return a;

     int ret;

     ret=getanc(block[a].father);
     block[a].dis+=block[block[a].father].dis;
     block[a].father=ret;

     return ret;
}

void union_set(int a,int b)
{
     int aa=getanc(a);
     int bb=getanc(b);
     block[bb].dis=block[aa].tot;//b元素的代表元素到代表元素的距离
     block[bb].father=aa;//b元素的代表元素父节点更新
     block[aa].tot+=block[bb].tot;//元素总个数更新
}
void print(int a)
{
     int aa=getanc(a);
     printf("%d\n",block[aa].tot-block[a].dis-1); //代表元素总个数-当前元素到代表元素的距离-本身=其下元素个数
}
int main()
{
    scanf("%d",&p);

    char s;
    int x,y;

    in();

    while(p--)
    {
         getchar();
         scanf("%c",&s);
         if(s=='M')
          {
          scanf("%d %d",&x,&y);
          union_set(x,y);
          }
         else {scanf("%d",&x);print(x);}
    }
    return 0;
}

你可能感兴趣的:(poj1988Cube Stacking(并查集+路径压缩))