IT民工
加油!

进行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;
}

 

 

posted on 2012-08-24 08:56  找回失去的  阅读(663)  评论(0编辑  收藏  举报