并查集(L3-003 社交集群 (30 分))

原题链接
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];
    }
}

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 程序猿惹谁了 设计师:白松林 返回首页