UVA 11987 Almost Union-Find

来源:互联网 发布:linux设置目录的权限 编辑:程序博客网 时间:2024/06/05 09:00

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3138

题目大意:有几个集合,有三种操作,1操作是合并p和q所在的集合,2操作是将p移动到q所在的操作,3操作是输出p所在的集合的所有元素的和。

#include<iostream>#include<cstring>#include<cstdio>using namespace std;const int mmax=200010;int kount[mmax],tree[mmax],sum[mmax],digit[mmax];int n,k,hehe;void init(){for(int i=1;i<=mmax;i++){tree[i]=sum[i]=digit[i]=i;kount[i]=1;}hehe=n;}int find(int x){return x==tree[x]?x:tree[x]=find(tree[x]);}void merge(int x,int y){int a=find(x);int b=find(y);if(a!=b){tree[a]=b;kount[b]+=kount[a];sum[b]+=sum[a];}}void move(int a){int z=find(digit[a]);kount[z]--;sum[z]-=a;digit[a]=++hehe;tree[hehe]=hehe;kount[hehe]=1;sum[hehe]=a;}int main(){while(~scanf("%d%d",&n,&k)){init();while(k--){int type,x,y;scanf("%d",&type);if(type==1){scanf("%d%d",&x,&y);merge(digit[x],digit[y]);}else if(type==2){scanf("%d%d",&x,&y);int a=find(digit[x]);int b=find(digit[y]);if(a!=b){move(x);merge(digit[x],digit[y]);}}else{int que;scanf("%d",&que);int a=find(digit[que]);printf("%d %d\n",kount[a],sum[a]);}}}}


原创粉丝点击