POJ 1988 Cube Stacking(带权的并查集)

题目链接:

http://poj.org/problem?id=1988

解题思路:

有很多个stack,一开始每个stack里面都有一个cube。

然后支持两种操作:

1.move x y: 将x所在的stack移动到y所在stack的顶部;

2.count x:查询在x所在stack中,在x之下的cube的个数。

算法思想:

带权的并查集。

设两个权值cnt[x],dis[x]分别代表以x为根结点的堆的碟子的个数和值为x的碟子到根结点的距离。

求x下面有多少碟子就等于cnt[pa[x]] - dis[x] - 1;

AC代码:

#include <iostream>
#include <cstdio>
using namespace std;

const int N = 30005;
int pa[N];
int dis[N];
int cnt[N];

int findset(int x){
    if(x == pa[x])
        return pa[x];
    int root = findset(pa[x]);
    dis[x] += dis[pa[x]];
    pa[x] = root;
    return pa[x];
}

int main(){
    int p;
    while(~scanf("%d",&p)){
        char op[5];
        int a,b;
        for(int i = 1; i <= N; i++){
            pa[i] = i;
            cnt[i] = 1;
            dis[i] = 0;
        }
        while(p--){
            scanf("%s",op);
            if(op[0] == 'M'){
                scanf("%d%d",&a,&b);
                a = findset(a);
                b = findset(b);
                if(a != b){
                    pa[b] = a;
                    dis[b] = cnt[a];
                    cnt[a] += cnt[b];
                }
            }
            else{
                scanf("%d",&a);
                b = findset(a);
                printf("%d\n",cnt[b]-dis[a]-1);
            }
        }
    }
    return 0;
}




你可能感兴趣的:(带权的并查集)