当你在社交网络平台注册时,一般总是被要求填写你的个人兴趣爱好,以便找到具有相同兴趣爱好的潜在的朋友。一个“社交集群”是指部分兴趣爱好相同的人的集合。你需要找出所有的社交集群。
输入格式:
输入在第一行给出一个正整数 N(≤),为社交网络平台注册的所有用户的人数。于是这些人从 1 到 N 编号。随后 N 行,每行按以下格式给出一个人的兴趣爱好列表:
Ki: [ [ ... [
其中(是兴趣爱好的个数,[是第j个兴趣爱好的编号,为区间 [1, 1000] 内的整数。
输出格式:
首先在一行中输出不同的社交集群的个数。随后第二行按非增序输出每个集群中的人数。数字间以一个空格分隔,行末不得有多余空格。
输入样例:
8
3: 2 7 10
1: 4
2: 5 3
1: 4
1: 3
1: 4
4: 6 8 1 5
1: 4
输出样例:
3 4 3 1
并查集模拟即可
#include<bits/stdc++.h> using namespace std; //input #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m); #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define LL long long #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define N 1020 int f[1020]; int ans[1020]; int vis[1020]; int find1(int x) { int j=x; while(j!=f[j]) j=f[j]; int cur=x; if(cur!=j) { int t=f[cur]; f[cur]=j; cur=t; } return j; } void union1(int x,int y) { int x1=find1(x); int y1=find1(y); if(x1!=y1)f[x1]=y1; return ; } int sum[N]; int main() { rep(i,0,1010) f[i]=i; int n; RI(n); while(n--) { int q; scanf("%d:",&q); int a;RI(a);vis[a]=1; rep(i,2,q) { int b; RI(b);vis[b]=1; union1(a,b); } sum[a]++; } int cnt=0; vector<int>v; v.clear(); rep(i,1,1000) if(vis[i]) { if(sum[i])ans[ find1(i) ]+=sum[i]; if(f[i]==i)cnt++; } rep(i,1,1000) if(ans[i]) v.push_back(ans[i]); sort(v.begin(),v.end(),greater<int>()); cout<<cnt<<endl; rep(i,0,v.size()-1) { if(i!=0)printf(" "); cout<<v[i]; } }