F - Almost Union-Find (UVA - 11987 )
阿新 • • 發佈:2018-02-15
include .... mos space 初始 gpo ret num std
- 題目大意
初始有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; }
F - Almost Union-Find (UVA - 11987 )