很简单一个并查集的题,理解题意默写模板即可ac。
#include <stdio.h> #include <memory.h> #include <math.h> #include <string> #include <vector> #include <set> #include <stack> #include <queue> #include <algorithm> #include <map> #define I scanf #define OL puts #define O printf #define F(a,b,c) for(a=b;a<c;a++) #define FF(a,b) for(a=0;a<b;a++) #define FG(a,b) for(a=b-1;a>=0;a--) #define LEN 1010 #define MAX (1<<30)-1 #define V vector<int> using namespace std; int fa[LEN]; void init(){ int i; F(i,1,LEN) fa[i]=i; } int findFa(int x){ if(fa[x]==x) return x; int r=x; //定义根 while(fa[r]!=r) { r=fa[r]; } //路径压缩 int t=x; //临时变量 while(fa[t]!=t) { t=fa[t]; //往上层根节点走, 让循环得以完成 fa[x]=r; //压缩路径 x=t; //更新x } return r; } void Union(int a,int b){ int fa_a=findFa(a); int fa_b=findFa(b); if(fa_a!=fa_b) fa[fa_a]=fa_b; } int hobby[LEN]; int cnt[LEN]; int n,m; int main(){ // freopen("1107.txt","r",stdin); I("%d",&n); init(); int i,j,t; F(i,1,n+1){ I("%d:",&m); FF(j,m){ I("%d",&t); if(hobby[t]!=0) Union(i,hobby[t]); else hobby[t]=i; } } F(i,1,n+1) cnt[findFa(i)]++; vector<int> ans; F(i,1,n+1) if(cnt[i]) ans.push_back(cnt[i]); sort(ans.begin(),ans.end()); reverse(ans.begin(),ans.end()); O("%d ",ans.size()); FF(i,ans.size()){ O("%d",ans[i]) ; if(i!=ans.size()-1) O(" "); } return 0; }