题目描述
当你在社交网络平台注册时,一般总是被要求填写你的个人兴趣爱好,以便找到具有相同兴趣爱好的潜在的朋友。一个“社交集群”是指部分兴趣爱好相同的人的集合。你需要找出所有的社交集群。
能搜这道题的差不多都一样,就不把题目照搬了
这道题我的想法是: 每个人都有一个集合,装着,自己的兴趣爱好,如果与其他人的兴趣集合(set的一个方法)有交集,就把他们连接起来(并查集),最后统计圈子的个数和里面人数的数量,找了半天也没看到有和自己想法相同的,就自己发出来看看(详细点的注释在代码上)
#include <bits/stdc++.h>
using namespace std;
set<int> id[1010]; //每个人的兴趣集合
int fa[1010]; //并查集
int cnt[1010]; //统计圈子数量
void init(int n) {
for (int i = 1 ; i <= n ; i++) fa[i] = i;
}
int find(int x) {
return x == fa[x] ? x : (fa[x] = find(fa[x]));
}
void merge(int x, int y) {
fa[find(x)] = find(y);
}
int main() {
int n;
cin >> n;
init(n);
int k,h;
scanf("%d: ", &k);
while (k-- ) {
cin >> h;
id[1].insert(h);
}
for (int i = 2 ; i <= n ; i++) {
int k,h;
set<int> st; //下面用来判断两个集合有没有交集
scanf("%d: ",&k);
while (k--) {
cin >> h;
id[i].insert(h);
}
for (int j = 1 ; j < i ; j++) {
set_intersection(id[j].begin(),id[j].end(),id[i].begin(),id[i].end(),inserter(st,st.begin()));
if (st.size()) merge(j,i);
st.clear(); //重置
}
}
//后面有点冗长,不过也没想其他方法优化了
for (int i = 1 ; i <= n ; i++) {
cnt[find(i)]++; //计数
}
sort(cnt+1,cnt+n+1,greater<int>());
int num =0;
for (int i = 1 ; i <= n ; i++) {
if (cnt[i]) num++;
}
cout << num<<endl;
int flag = 0;
for (int i = 1 ; i <= n ; i++) {
if (cnt[i]) {
if (!flag) {
cout << cnt[i];
flag = 1;
} else cout << " " <<cnt[i];
}
}
}
学习愉快!!!