1107 Social Clusters (30point(s)) - C語言 PAT 甲級

1107 Social Clusters (30point(s))

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 (≤1000), 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 (>0) is the number of hobbies, and hi​​[j] 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

題目大意:

輸入 N 個人的愛好,若有兩個人有相同的愛好,則這兩個人視爲在同一社交圈,求所有人構成了多少社交圈數量,並輸出每個社交圈的人數,從大到小排序

設計思路:

並查集

  • 社交圈是人組成的,愛好僅是判斷兩人是否在同一社交圈的媒介
  • hobby[] 數組記錄當前愛好有無人喜歡
    • 若還沒有,自己佔據此愛好,當作此社交圈的祖先
    • 若有人,則把自己加入此社交圈
  • 對每個人進行遍歷,記錄組成了多少社交圈,和每個社交圈的人數
編譯器:C (gcc)
include <stdio.h>

int cmp(const void *a, const void *b)
{
        return *((int *)b) - *((int *)a);
}

int father[1010], rank[1010];

void makeset()
{
        int i;
        for (i = 0; i < 1010; i++) {
                father[i] = i;
                rank[i] = 0;
        }
}

int getfather(int v)
{
        if (father[v] == v)
                return v;
        father[v] = getfather(father[v]);
        return father[v];
}

void judge(int x, int y)
{
        int fx = getfather(x);
        int fy = getfather(y);
        if (rank[fx] > rank[fy]) {
                father[fy] = fx;
        } else {
                father[fx] = fy;
                if (rank[fx] == rank[fy])
                        rank[fy]++;
        }
}

int main(void)
{
        int n;
        int hobby[1010] = {0}, result[1010] = {0};
        int i, j, k, a;

        makeset();
        scanf("%d", &n);
        for (i = 1; i <= n; i++) {
                scanf("%d:", &k);
                while (k--) {
                        scanf("%d", &a);
                        if (hobby[a] == 0)
                                hobby[a] = i;
                        else
                                judge(hobby[a], i);
                }
        }
        for (i = 1; i <= n; i++)
                result[getfather(i)]++;
        qsort(result + 1, n, sizeof(result[0]), cmp);
        for (i = 1; i <= n && result[i] > 0; i++)
                ;
        printf("%d\n", i - 1);
        for (j = 1; j < i; j++)
                printf("%s%d", j > 1 ? " " : "", result[j]);
        return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章