您的位置:首页 > 其它

hdu 2818 带权并查集

2013-01-13 14:05 232 查看
/*题目大意:
有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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: