题解 并查集 POJ 1988

题意:N(N<=30,000)堆方块,开始每堆都是一个方块。方块编号1– N. 有两种操作:
  M x y : 表示把方块x所在的堆,拿起来叠放到y所在的堆上。
  C x : 问方块x下面有多少个方块。
  操作最多有 P(P<=100,000)次。对每次C操作,输出结果。
做法:对N个方块设为N个堆。每次进行操作时将两个堆合并。对每个元素的下面方块的 数量进行记录和维护。每次合并时将放在上面的堆的根放在最下面。再用一个数组 记录每个堆的方块总数。
代码:
#include <iostream>
#include <cstdio>
using namespace std;
const int MAX=30000;
int par[MAX+10],total[MAX+10],under[MAX+10];
int get(int a)
{
    if(par[a]==a)
        return a;
    int t=get(par[a]);
        under[a]+=under[par[a]];
        par[a]=t;
    return par[a];
}
void merge(int a,int b)
{
    int p1=get(a);
    int p2=get(b);
    if(p1==p2)
        return ;
    par[p2]=p1;
    under[p2]=total[p1];
    total[p1]=total[p1]+total[p2];

}
int main()
{
    int T,a,b,i;
    char ch;
    for(i=0;i<MAX+10;i++)
        under[i]=0,par[i]=i,total[i]=1;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s",&ch);
        if(ch=='M')
        {scanf("%d%d",&a,&b);merge(b,a);}
        if(ch=='C')
        {scanf("%d",&a);get(a);printf("%d\n",under[a]);}
    }
    return 0;
}

posted on 2014-07-24 15:12  一锅土豆  阅读(135)  评论(0编辑  收藏  举报