这个题是一个合并并查集节点的一道题,首先要明白的是并起来的元素就相当于一颗二叉树一样,所以不可能随便的将一个二叉树的根节点删除掉,所以我们只能让它保持在她的原位但是废弃掉它所有的功能。所以,我们需要给每一个节点都给他一张能识别它的身份证,当我们要废除掉一个节点的时候,先废除掉她的功能,然后新开一个点来表示它,再把它和别的节点合并起来。
#include<bits/stdc++.h>
using namespace std;
int data[1000100],sum[1000010],cnt[1000010],id[1000010],n;
void init()
{
int i;
for(i=1;i<=n;i++)
{
data[i]=i;
sum[i]=i;
cnt[i]=1;
id[i]=i;
}
}
int getf(int x)
{
if(x==data[x])
{
return x;
}
else
{
return data[x]=getf(data[x]);
}
}
int main()
{
int m,i,j,k,a,b,num;
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
num=n+1;
while(m--)
{
scanf("%d",&k);
if(k==1)
{
scanf("%d%d",&a,&b);
int x,y;
x=id[a];
y=id[b];
x=getf(x);
y=getf(y);
if(x!=y)
{
data[y]=x;
sum[x]+=sum[y];
cnt[x]+=cnt[y];
}
}
else if(k==2)
{
scanf("%d%d",&a,&b);
int x,y;
x=id[a];
y=id[b];
x=getf(x);
y=getf(y);
if(x!=y)
{
sum[x]-=a;
cnt[x]--;
id[a]=num++;
x=id[a];
data[x]=y;
cnt[y]+=1;
sum[y]+=a;
}
}
else
{
int x,y;
scanf("%d",&x);
x=id[x];
x=getf(x);
printf("%d %d\n",cnt[x],sum[x]);
}
}
}
return 0;
}