- 题目大意
初始有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\n",num[fx],sum[fx]); } } } return 0; }