hdu 2818 带权并查集

来源:互联网 发布:c语言 获取时间毫秒 编辑:程序博客网 时间:2024/05/16 07:18
/*题目大意:有N个砖头,编号为1~N,  然后有两种操纵,第一种是M  x  y, 把x地点的那一堆砖头全部移动放到y地点的那堆的上方。第二种操纵是C  x,  即查询x下面有几许个砖头,并且输出。*/#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;const int maxn=30002;int p,fa[maxn],up[maxn],sum[maxn];// up[i] 表示节点 i 之上有多少个节点// sum[i] 表示节点i及之下有多少个节点char op[2];int find(int i){    if(fa[i]==i)return i;    int ans=fa[i];    fa[i]=find(fa[i]);    up[i]+=up[ans];//当前节点 加上原先的父节点个数    return fa[i];}void Union(int u,int v){    fa[v]=u;    up[v]=sum[u];    sum[u]+=sum[v];}int main(){    //freopen("//media/学习/ACM/input.txt","r",stdin);    while(scanf("%d",&p)!=EOF)    {        int u,v;        for(int i=0;i<maxn;i++)fa[i]=i,sum[i]=1,up[i]=0;        while(p--)        {            cin>>op;            if(op[0]=='M')            {                scanf("%d%d",&u,&v);                int x=find(u);                int y=find(v);                if(x!=y)                {                    Union(x,y);                }            }else            {                scanf("%d",&u);                int y=find(u);                printf("%d\n",sum[y]-up[u]-1);            }        }    }    return 0;}

原创粉丝点击