SPOJ IAPCR2F 【并查集】
思路:
利用并查集/DFS都可以处理连通问题。
PS:注意Find()查找值和pre[]值的区别。
#include<bits/stdc++.h> using namespace std; const int N=1e3+10; int val[N]; int pre[N],n,m; vector<int>xs,ans; int Find(int x) { int r=x; while(pre[r]!=r) r=pre[r]; int i=x,j; while(pre[i]!=r) { j=pre[i]; pre[i]=r; i=j; } return r; } int main() { int T,cas=1,x,y; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&val[i]); pre[i]=i; } while(m--) { scanf("%d%d",&x,&y); x=Find(x); y=Find(y); if(x!=y) pre[x]=y; } xs.clear(); ans.clear(); for(int i=1;i<=n;i++) if(pre[i]==i) xs.push_back(i); int sz=xs.size(); for(int i=0;i<sz;i++) { int sum=0; for(int j=1;j<=n;j++) if(Find(j)==xs[i]) sum+=val[j]; ans.push_back(sum); } sort(ans.begin(),ans.end()); sz=ans.size(); printf("Case %d: %d\n",cas++,sz); for(int i=0;i<sz;i++) { if(i) printf(" "); printf("%d",ans[i]); } puts(""); } return 0; }