- 题目大意
初始有N个集合,分别为 1 ,2 ,3 .....n。一共有三种操件:
1、 p q 合并元素p和q的集合
2 、p q 把p元素移到q集合中
3 、p 输出p元素集合的个数及全部元素的和。
- 解题思路
并查集操作。1、3步比较容易实现,只要建立一个sum[],cnt[],记录每个结点相应值,和并时把值更新到根结点,输出时只要找到根结点输出其值即可。第二步可以利用并查集的删除功能去构造即可。
- 代码
#include<cstdio>
using namespace std;
const int MAX=1e5+50;
int fa[MAX];
int num[MAX],id[MAX];
long long sum[MAX];
int find(int x)
{
if(x==fa[x])
return x;
else
return fa[x]=find(fa[x]);
}
void init(int n)
{
for(int i=0;i<=n;i++)
{
sum[i]=fa[i]=id[i]=i;
num[i]=1;
}
}
void Union(int x,int y)
{
int fx=find(x),fy=find(y);
if(fx!=fy)
{
fa[fx]=fy;
sum[fy]+=sum[fx];
num[fy]+=num[fx];
}
}
int main()
{
int n,m,x,y,tmp;
while(scanf("%d%d",&n,&m)!=EOF)
{
tmp=n;
init(n);
int choose;
while(m--)
{
scanf("%d",&choose);
if(choose==1)
{
scanf("%d%d",&x,&y);
Union(id[x],id[y]);
}
else if(choose==2)
{
scanf("%d%d",&x,&y);
int fx=find(id[x]),fy=find(id[y]);
if(fx!=fy)
{
sum[fx]-=x;
num[fx]--;
tmp++;
id[x]=tmp;
fa[tmp]=tmp;
num[tmp]=1;
sum[tmp]=x;
Union(id[x],id[y]);
}
}
else
{
scanf("%d",&x);
int fx=find(id[x]);
printf("%d %d
",num[fx],sum[fx]);
}
}
}
return 0;
}