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