原题链接
L3-003 社交集群 (30 分)
当你在社交网络平台注册时,一般总是被要求填写你的个人兴趣爱好,以便找到具有相同兴趣爱好的潜在的朋友。一个“社交集群”是指部分兴趣爱好相同的人的集合。你需要找出所有的社交集群。
输入格式:
输入在第一行给出一个正整数 N(≤1000),为社交网络平台注册的所有用户的人数。于是这些人从 1 到 N 编号。随后 N 行,每行按以下格式给出一个人的兴趣爱好列表:
输出格式:
首先在一行中输出不同的社交集群的个数。随后第二行按非增序输出每个集群中的人数。数字间以一个空格分隔,行末不得有多余空格。
输入样例:
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
分析:通过分析,我们可以对爱好进行并查集,统计一个社交集群的相关爱好。之后,在对f数组进行循环,统计有多少个爱好。在此之前,用ind记录第i个人的任意一个爱好,在循环一次统计。排序输出,over。
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
const int maxn = 1005;
int ind[maxn + 1];
int f[maxn + 1];
int book[maxn + 1];
int ans[maxn + 1];
bool cmp (int a, int b) {
return a > b;
}
void init() {
for(int i = 0; i <= maxn; i++) {
f[i] = i;
}
}
int find(int x) {
int tem1 = x,tem2;
while (f[x] != x) {
x = f[x];
}
while(tem1 != x) {
tem2 = f[tem1];
f[tem1] = x;
tem1 = tem2;
}
return x;
}
void Union(int a, int b) {
int f_a = find(a);
int f_b = find(b);
if (f_a != f_b) {
f[f_a] = f_b;
}
}
int main() {
int n,m = 0;
cin >> n;
init();
for (int i = 1; i <= n; i++) {
int flag = 0,tem;
cin >> m;
getchar();
for (int j = 1; j <= m; j++) {
cin >> tem;
if (j == 1) {
flag = tem;
ind[i] = tem;
} else {
Union(flag,tem);
}
book[tem] = 1;
}
}
set<int >cp;
for(int i = 1; i <= maxn; i++) {
if (book[i]) {
cp.insert(find(i));
}
}
for (int i = 1; i <= n; i++) {
ans[find(ind[i])]++;
}
sort(ans + 1, ans + maxn + 1,cmp);
int cnt = int(cp.size());
cout << cnt <<endl;
for (int i = 1; i <= cnt; i++) {
if(i != 1) {
cout << " ";
}
cout << ans[i];
}
}