• PAT甲级——1107 Social Clusters (并查集)


    本文同步发布在CSDN:https://blog.csdn.net/weixin_44385565/article/details/90409731

    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

    题目大意:将N个人按照兴趣爱好分类,爱好有交集的归为一个社交团体,求社交团体的个数,然后将团体里面的人数进行降序输出。 

    思路:在并查集的操作上稍作修改,用根节点的值进行人数的统计,以每一行的第一个爱好代号作为当前数据的root,将之后的X与root进行union操作,若S[rootX]不等于root且 ≤ 0,意味着当前团体已经有了 | S[rootX] | 人,将S[rootX]的值加到S[root]上再进行合并。注意每一行开头的K:需要用字符串数组处理来获取K的值。

     1 #include <iostream>
     2 #include <vector>
     3 #include <cmath>
     4 #include <algorithm>
     5 #define MaxNum 1001
     6 using namespace std;
     7 vector <int> S(MaxNum, 0);
     8 bool cmp(int a, int b) {
     9     return a > b;
    10 }
    11 int getK(char *c);
    12 void unionSet(int root, int X);
    13 int find(int X);
    14 int main()
    15 {
    16     int N, K;
    17     scanf("%d", &N);
    18     for (int i = 0; i < N; i++) {
    19         int root, X;
    20         char c[5];
    21         scanf("%s%d", c, &X);
    22         K = getK(c);
    23         root = find(X);
    24         S[root]--;//人数+1用负数表示
    25         for (int j = 1; j < K; j++) {
    26             scanf("%d", &X);
    27             unionSet(root, X);    
    28         }
    29     }
    30     vector <int> ans;
    31     for (int i = 1; i < MaxNum; i++) {
    32         if (S[i] < 0)
    33             ans.push_back(abs(S[i]));
    34     }
    35     sort(ans.begin(), ans.end(), cmp);
    36     printf("%d
    ", ans.size());
    37     printf("%d", ans[0]);
    38     for (int i = 1; i < ans.size(); i++)
    39         printf(" %d", ans[i]);
    40     printf("
    ");
    41     return 0;
    42 }
    43 int getK(char *c) {
    44     int sum = 0;
    45     for (int i = 0; c[i] != ':'; i++)
    46         sum = sum * 10 + c[i] - '0';
    47     return sum;
    48 }
    49 void unionSet(int root, int X) {
    50     int rootX = find(X);
    51     if(S[rootX] <=0 && rootX != root){
    52         S[root] += S[rootX];
    53         S[rootX] = root;
    54     }
    55 }
    56 int find(int X) {
    57     if (S[X] <= 0)
    58         return X;
    59     else
    60         return S[X] = find(S[X]);//递归地压缩路径
    61 }
  • 相关阅读:
    归并排序
    mysql优化
    树结构
    urllib库的使用
    linux常用命令
    mysql慢查询
    支付宝第三方支付
    类型(type)判断
    c语言自带的排序与查找
    多字节与宽字节转换
  • 原文地址:https://www.cnblogs.com/yinhao-ing/p/10900798.html
Copyright © 2020-2023  润新知