PAT

来源:互联网 发布:知乎周刊plus 日语 编辑:程序博客网 时间:2024/06/14 21:34

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 (<=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个人
每个人有k个hobby
然后有相同hobby的人就属于一类人
求 一共有几个分类以及每个聚类中有多少人
很明显并查集
不过时间充足我暴力了……

code

/*另类并查集思想并查集的节点(hobby)不带秩而使用peoNum来记录节点的'秩'进而暴力累加某一类的peoNum*/#include <bits/stdc++.h>using namespace std;int peoNum[1110];  /// 某个hobby代表的人的数量int root[1110];    /// 并查集-父节点bool status[1110]; /// status 证明是否有这个hobby序号int ans[1110];     /// 每个'聚类'中人的数量void init(){    for(int i=0; i<=1000; i++)    {        root[i] = i;        peoNum[i] = 0;        status[i] = 0;        ans[i] = 0;    }}int fd(int x){    if(x != root[x])    {        root[x] = fd(root[x]);    }    return root[x];}void un(int x,int y){    x = fd(x);    y = fd(y);    root[x] = y;}bool cmp(int x,int y){    return x >= y;}int main(){    char c; /// 吃冒号....    int n,i,j,k,x,y;    vector <int> father; ///保存根的信息    init();    cin>>n;    for(i=1; i<=n; i++)    {        cin>>k>>c;        cin>>y;        status[y] = 1;        peoNum[y]++; /// 第一个节点就可以代表一个人 这样不会记录重复的人数        for(j=2; j<=k; j++)        {            cin>>x;            status[x] = 1;            un(y,x);        }    }    int cnt = 0; /// 记录'聚类'    for(i=1; i<=1110; i++)    {        if(status[i]==1 && root[i] == i)        {            cnt++;            father.push_back(i);        }    }    cout<<cnt<<endl;    for(i=0; i<father.size(); i++) /// 暴力-找父节点所在聚类的人数加和    {        for(j=0; j<1110; j++)        {            if(status[j] == 1 && fd(j) == father[i])            {                ans[i] += peoNum[j];            }        }    }    sort(ans,ans+father.size(),cmp);    for(i=0; i<father.size(); i++)    {        if(i == 0)        {            cout<<ans[i];        }        else        {            cout<<" "<<ans[i];        }    }    cout<<endl;    return 0;}
原创粉丝点击