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
题意:有一群人每个人都有各自的兴趣,如果兴趣有重叠的部分就认为是同一个group。现给定每个人的兴趣list,问你共有几个group及每个group的人数(从大到小输出)
解法:并查集
还是维护以人为结点的森林,这里还需要一个数组去维护每个兴趣对应的“头”。这其实是在每一次更新的时候处理。
一开始初始化为0,如这个兴趣还没有人有,则将值赋为当前的人的编号。否则就将该兴趣对应的人和当前的人进行unite。
再将所有的兴趣对应的人更新为当前的”头“ 。(其实可能不用、不过这样更明确一点)
然后就可以了,统计每个人群的人数,这里为了方便用了priority_queue。
#include <bits/stdc++.h>
#define pii pair<int, int>
#define ll long long
#define eps 1e-5
using namespace std;
const int oo = 0x7fffffff;
const int maxn = 1e4 + 10;
int par[maxn];
int hobby[maxn];
void init(int n)
{
for(int i = 1; i <= n; i++)
par[i] = i;
}
int f(int x)
{
if(x == par[x])
return x;
return par[x] = f(par[x]);
}
void unite(int x, int y)
{
x = f(x);
y = f(y);
par[x] = y;
}
int main()
{
// freopen("/Users/vector/Desktop/testdata.in", "r", stdin);
// ios::sync_with_stdio(false);
// cin.tie(0);
int n;
scanf("%d", &n);
init(n);
for(int i = 1; i <= n; i++)
{
int m;
scanf("%d:", &m);
while(m--)
{
int t;
scanf("%d", &t);
if(hobby[t] == 0)
hobby[t] = i;
else
{
unite(i, hobby[t]);//如果当前兴趣已经存在则进行合并
hobby[t] = f(i);
}
}
}
map<int, int> q;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
if(f(j) == i)
q[i]++;
}
priority_queue<int> ans;
for(auto idx: q)
ans.push(idx.second);
int cnt = (int)ans.size();
printf("%d\n", cnt);
while(ans.size())
{
printf("%d", ans.top());
ans.pop();
if(cnt > 1)
putchar(' ');
else
putchar('\n');
cnt--;
}
return 0;
}