PTA 天梯赛 L3-003 社交集群(并查集)

当你在社交网络平台注册时,一般总是被要求填写你的个人兴趣爱好,以便找到具有相同兴趣爱好的潜在的朋友。一个“社交集群”是指部分兴趣爱好相同的人的集合。你需要找出所有的社交集群。

输入格式:

输入在第一行给出一个正整数 N(≤1000),为社交网络平台注册的所有用户的人数。于是这些人从 1 到 N 编号。随后 N 行,每行按以下格式给出一个人的兴趣爱好列表:

Ki: hi[1] hi[2] ... hi[Ki]

其中Ki(>0)是兴趣爱好的个数,hi[j]是第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
// 并查集模板
// Author : RioTian
// Time : 20/11/08
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e3 + 10;
int f[N], a[N], cir[N];
int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }
void merge(int x, int y) {
    x = find(x), y = find(y);
    if (x != y) f[x] = y;
}
int main() {
    // freopen("in.txt", "r", stdin);
    // ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int n, k, x;
    char ch;
    cin >> n;
    for (int i = 0; i <= 1000; ++i) f[i] = i;
    for (int i = 1; i <= n; ++i) {
        cin >> k >> ch;
        for (int j = 1; j <= k; ++j) {
            cin >> x;
            if (a[x] == 0) a[x] = i;  // i号人作为爱好x的父亲
            merge(i, find(a[x]));     //将i号人与爱好x的人群连接
        }
    }
    for (int i = 1; i <= n; ++i) cir[find(i)]++;
    sort(cir + 1, cir + 1 + n, greater<int>());  //按从大到小排序
    int i;
    for (i = 1; i <= 1000; ++i)
        if (cir[i] == 0) {
            i--;
            break;
        }
    cout << i << endl;
    for (int j = 1; j <= i; j++) {
        if (j == 1)
            cout << cir[j];
        else
            cout << " " << cir[j];
    }
    cout << endl;
    return 0;
}

Code update

// Murabito-B 21/04/23
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int f[1010], a[1010], cir[1010];
int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
void merge(int x, int y) { f[find(x)] = f[find(y)]; }
void solve() {
    int n, k, x;
    char c;
    cin >> n;
    for (int i = 0; i <= 1000; ++i) f[i] = i;
    for (int i = 1; i <= n; ++i) {
        cin >> k >> c;
        while (k--) {
            cin >> x;
            if (!a[x]) a[x] = i; // i号人作为爱好x的父亲
            merge(i, a[x]);      //将i号人与爱好x的人群连接
        }
    }
    for (int i = 1; i <= n; ++i) cir[find(i)]++;
    sort(cir + 1, cir + n + 1, greater<int>()); //按从大到小排序
    int i = 1;
    for (; i <= 1000; ++i)
        if (!cir[i]) {
            i--;
            break;
        }
    cout << i << "\n";
    for (int j = 1; j <= i; ++j) {
        if (j == 1) cout << cir[j];
        else
            cout << " " << cir[j];
    }
    cout << "\n";
}
int main() {
    ios_base::sync_with_stdio(false), cin.tie(0);
    solve();
    return 0;
}
posted @ 2020-11-08 14:43  RioTian  阅读(258)  评论(0编辑  收藏  举报