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.
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].
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.
8
3: 2 7 10
1: 4
2: 5 3
1: 4
1: 3
1: 4
4: 6 8 1 5
1: 4
3
4 3 1
题意:有一群人每个人都有各自的兴趣,如果兴趣有重叠的部分就认为是同一个group。现给定每个人的兴趣list,问你共有几个group及每个group的人数(从大到小输出)
解法:并查集
还是维护以人为结点的森林,这里还需要一个数组去维护每个兴趣对应的“头”。这其实是在每一次更新的时候处理。
一开始初始化为0,如这个兴趣还没有人有,则将值赋为当前的人的编号。否则就将该兴趣对应的人和当前的人进行unite。
再将所有的兴趣对应的人更新为当前的”头“ 。(其实可能不用、不过这样更明确一点)
然后就可以了,统计每个人群的人数,这里为了方便用了priority_queue。
#include
#define pii pair
#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 q;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
if(f(j) == i)
q[i]++;
}
priority_queue 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;
}