POJ 1988 Cube Stacking

进行m次操作,M x y 将包含x的集合移动到y上面,C x, 计算x下面有几个元素。用p[x]表示x的根结点,

cnt[x]表示x所在集合的元素个数,top[x]表示x上面有几个元素。每次进行路径压缩时,top[x]都要加上

top[p[x]],cnt和p的操作就是并查集的基本操作。最后计算结果是用x所在集合元素的个数 - 在它之上

的个数 - 它本身。

/*Accepted    500K    297MS    C++    1147B    2012-08-24 08:41:18*/

#include<stdio.h>

#include<string.h>

#include<stdlib.h>



const int MAXN = 30030;

int p[MAXN], cnt[MAXN], top[MAXN], m;



int find_set(int x)

{

    int t;

    if(x != p[x])

    {

        t = p[x];

        p[x] = find_set(p[x]);

        top[x] += top[t];

    }

    return p[x];

}



void union_set(int x, int y)

{

    int nx, ny;

    nx = find_set(x), ny = find_set(y);

    if(nx != ny)

    {

        p[ny] = nx;

        top[ny] = cnt[nx];

        cnt[nx] += cnt[ny];

    }

}



void operation()

{

    int i, x, y;

    char op[5];

    for(i = 1; i < MAXN; i ++)

    {

        p[i] = i, cnt[i] = 1, top[i] = 0;

    }

    scanf("%d", &m);

    while(m --)

    {

        scanf("%s", op);

        if('M' == op[0])

        {

            scanf("%d%d", &x, &y);

            union_set(x, y);

        }

        else

        {

            scanf("%d", &x);

            int ans, nx;

            nx = find_set(x);

            ans = cnt[nx] - top[x] - 1;

            //x所在集合的元素个数 - 在它上面的个数 - 它本身 就是在它之下的个数

            printf("%d\n", ans);

        }

    }

}



int main()

{

    operation();

    return 0;

}

 

 

你可能感兴趣的:(stack)