PAT甲级1107Social Clusters

题目链接

https://pintia.cn/problem-sets/994805342720868352/problems/994805361586847744

题解

题目要求

  • 输入
    • N:正整数,不超过1000,人的数量,索引为[1,N]
    • N个人的爱好:爱好的索引为[1,1000]
  • 输出
    • 有几个类(如果两人有共同爱好,则他们属于同一类)
    • 每类的人数

解题思路

代码

// Problem: PAT Advanced 1107
// URL: https://pintia.cn/problem-sets/994805342720868352/problems/994805361586847744
// Tags: 并查集 路径压缩

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

vector<int> father, clusterSize;
int likeHobby[1001]; // 保存这一爱好的代表人(任意)

int findFather(int x){
    return father[x] == x ? x : father[x] = findFather(father[x]); // 路径压缩
    // return father[x] == x ? x : findFather(father[x]);
}

void UNION(int a, int b){
    int fa = findFather(a), fb = findFather(b);
    if (fa != fb)
        father[fa] = fb;
}

bool cmp(int& a, int& b){
    return a > b;
}

int main()
{
    int n, k, hobby;
    scanf("%d", &n);
    father.resize(n+1);
    clusterSize.resize(n+1);
    for (int i = 0; i < father.size(); i++) // 初始化,每人都是一个cluster
        father[i] = i;
    for (int i = 1; i <= n; i++){
        scanf("%d:", &k);
        for (int j = 0; j < k; j++){
            scanf("%d", &hobby);
            if (likeHobby[hobby] == 0)
                likeHobby[hobby] = i;
            UNION(i, likeHobby[hobby]); // 将i和他的爱好的代表人合并
        }
    }

    // 统计每个cluster的人数
    for (int i = 1; i <= n; i++){
        clusterSize[findFather(i)]++;
    }
    sort(clusterSize.begin(), clusterSize.end(), cmp);
    int cnt = 0;
    while (clusterSize[cnt] > 0){
        cnt++;
    }
    printf("%d
", cnt);
    if (cnt > 0){
        printf("%d", clusterSize[0]);
        for (int i = 1; i < cnt; i++)
            printf(" %d", clusterSize[i]);
    }
    return 0;
}

参考链接

https://zhuanlan.zhihu.com/p/93647900

https://blog.csdn.net/liuchuo/article/details/52191082


作者:@臭咸鱼

转载请注明出处:https://www.cnblogs.com/chouxianyu/

欢迎讨论和交流!


原文地址:https://www.cnblogs.com/chouxianyu/p/13837410.html