题意是需要写一个不相交集,有三种操作,第一种是,把包含片p和q元素的集合合并,如果p、q在同一集合,则忽视这个操作
第二种操作是把p加入到q所在的集合,如果p、q在同一集合,则忽视这个操作
第三中操作,输出p所在集合的元素个数与元素和。
第一种操作直接用并查集的合并即可,第三中操作用一个sum数组和size数组储存即可。
麻烦的是第二种操作,直接合并p和q的话是不可取的,需要把这个p从原有集合中删除,然后把这个点的信息插入末尾,此时需要一个数组real来存储所有元素的真实编号,然后在与q合并。
#include<stdio.h>
int pre[200002];
int size[200002];
int sum[200002];
int real[100002];
int cnt;
int find(int x)
{
if(x==pre[x]) return x;
else{
pre[x]=find(pre[x]);
return pre[x];
}
}
int main(void)
{
int n,m;
int o,p,q;
while(scanf("%d%d",&n,&m)!=EOF)
{
cnt=n;
for(int i=1;i<=n;i++)
{
pre[i]=i;
real[i]=i;
sum[i]=i;
size[i]=1;
}
for(int i=1;i<=m;i++)
{
scanf("%d",&o);
if(o==1){
scanf("%d%d",&p,&q);
int tx=find(real[p]),ty=find(real[q]);
if(tx!=ty)
{
pre[tx]=ty;
sum[ty]+=sum[tx];
size[ty]+=size[tx];
}
}
else if(o==2){
scanf("%d%d",&p,&q);
int tx=find(real[p]),ty=find(real[q]);
if(tx!=ty){
sum[tx]-=p;
size[tx]--;
real[p]=(++cnt);
pre[real[p]]=ty;
sum[ty]+=p;
size[ty]++;
}
}
else{
scanf("%d",&p);
int fp=find(real[p]);
printf("%d %d\n",size[fp],sum[fp]);
}
}
}
}