PAT A1107 Social Clusters 题解及注意事项

1107 Social Clusters (30分)

When register on a social network, you are always asked to specify your hobbies in order to find some potential friends with the same hobbies. A social cluster is a set of people who have some of their hobbies in common. You are supposed to find all the clusters.

Input Specification:

Each input file contains one test case. For each test case, the first line contains a positive integer N (≤), the total number of people in a social network. Hence the people are numbered from 1 to N. Then N lines follow, each gives the hobby list of a person in the format:

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

where Ki​​ (>) is the number of hobbies, and [ is the index of the j-th hobby, which is an integer in [1, 1000].

Output Specification:

For each case, print in one line the total number of clusters in the network. Then in the second line, print the numbers of people in the clusters in non-increasing order. The numbers must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input:

8
3: 2 7 10
1: 4
2: 5 3
1: 4
1: 3
1: 4
4: 6 8 1 5
1: 4
 

Sample Output:

3
4 3 1

思路:

关于并查集:并查集-https://www.cnblogs.com/tao10203/p/13855118.html

和"好朋友"问题类似,如果A和B是好朋友,B和C是好朋友,那么A和C就是好朋友,即如果A选了1,2课,B选了1课,C选了2课,那么A,B,C就是同一个cluster中的人,本题中判断两个人是好朋友的条件是他们有公共喜欢的课程,因此不妨开一个数组course,其中course[t]记录任意一个喜欢课程t的人,这样findFather(course[t])就是喜欢这个课的人应该所在的集合的根节点。于是,对当前读入的人的编号I和他喜欢的每个活动t,进行Union(i,course[t])即可。

Solution(C/C++):

#include <bits/stdc++.h>

using namespace std;

const int maxn = 10010;

int father[maxn],
    course[maxn] = {
        0};  // chourse[i] 存任意一个喜欢课程i的人,反正一合并都在一个集合里

void init(int n) {
    for (int i = 0; i <= n; ++i) {
        father[i] = i;
    }
}
int findFather(int x) {
    if (x == father[x])
        return x;  // x就是根节点
    else {
        int F = findFather(father[x]);  //查找他的父亲
        father[x] = F;
        return F;
    }
}

void Union(int a, int b) {
    int Fa = findFather(a);
    int Fb = findFather(b);
    if (Fa != Fb) father[Fb] = Fa;
}

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

int main() {
    int n, k, t;
    cin >> n;
    init(n);
    for (int i = 1; i <= n; ++i) {
        scanf("%d: ", &k);  //吸收‘:’符号

        for (int j = 0; j < k; ++j) {
            cin >> t;
            if (course[t] == 0) {
                course[t] = i;  //如果还没人喜欢课程t,就指定他是喜欢t的人之一
            }
            Union(i, course[t]);  // 让i和喜欢course[t]合并到同一个集合
        }
    }
    int cnt = 0;
    int cluster[maxn] = {0};
    bool isroot[maxn] = {false};
    fill(isroot, isroot + maxn, false);
    for (int i = 1; i <= n; ++i) {
        int F = findFather(i);
        if (isroot[F] == false) {
            isroot[F] = true;
            cnt++;
        }
        cluster[F]++;
    }
    cout << cnt << endl;
    sort(cluster + 1, cluster + n + 1, cmp);
    for (int i = 1; i <= cnt; ++i) {
        cout << cluster[i];
        if (i < cnt) cout << " ";
    }
    return 0;
}

 

posted @ 2020-10-21 22:49  tao10203  阅读(166)  评论(0)    收藏  举报