[并查集] 1107. Social Clusters (30)

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

 

分析:这是一道并查集的题目,但是需要注意的是,我们集合的元素是人,而不是爱好,所以需要一个映射,将每一个爱好的编号映射成人的编号,再对人进行并的操作。另外,如何使用并查集求每个集合的元素,我们只需要新增加一个计数的数组,每次进行合并操作时,将对应的计数数组进行相加即可。

 

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

const int maxn=1100;
const int INF=1e9;

int father[maxn];
int num[maxn];
int hobby[maxn];

void init()
{
    for(int i=0;i<maxn;i++)
    {
        father[i]=i;
        num[i]=1;
        hobby[i]=-1;
    }
}

int findFather(int x) 
{
    int a=x;
    while(x!=father[x]) x=father[x];
    while(a!=father[a])
    {
        int z=a;
        a=father[a];
        father[z]=x;
    }
    return x;
}

int cnt;

void uf(int a,int b)
{
    int fa=findFather(a);
    int fb=findFather(b);
    if(fa!=fb)
    {
        father[fa]=fb;
        num[fb]+=num[fa];
        cnt--;
    }
}

int n;

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

int main()
{
    init();
    cin>>n;
    cnt=n;
    for(int i=1;i<=n;i++)
    {
        int k;
        scanf("%d: ",&k);
        for(int j=0;j<k;j++)
        {
            int kj;
            cin>>kj;
            if(hobby[kj]==-1)
            {
                hobby[kj]=i;
            }
            else
            {
                uf(hobby[kj],i);
            }
        }
    }
    cout<<cnt<<endl;
    vector<int> ans;
    for(int i=1;i<=n;i++)
    {
        if(father[i]==i) ans.push_back(num[i]);
    }
    sort(ans.begin(),ans.end(),cmp);
    for(int i=0;i<ans.size();i++)
    {
        if(i>0) cout<<" ";
        cout<<ans[i];
    }
    return 0;
}

 

posted @ 2017-02-28 13:23  Num.Zero  阅读(303)  评论(0编辑  收藏  举报