L3-003. 社交集群
时间限制
1000 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越
在社交网络平台注册时,用户通常会输入自己的兴趣爱好,以便找到和自己兴趣相投的朋友。有部分兴趣相同的人们就形成了“社交集群”。现请你编写程序,找出所有的集群。
输入格式:
输入的第一行给出正整数N(<=1000),即社交网络中的用户总数(则用户从1到N编号)。随后N行,每行按下列格式列出每个人的兴趣爱好:
Ki: hi[1] hi[2] ... hi[Ki]
其中Ki(>0)是第i个人的兴趣的数量,hi[j]是第i个人的第j项兴趣的编号,编号范围为[1, 1000]内的整数。
输出格式:
首先在第一行输出整个网络中集群的数量,然后在第二行按非递增的顺序输出每个集群中用户的数量。数字间以1个空格分隔,行首尾不得有多余空格。
输入样例: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
思路:每一个人用第一个兴趣编号作为代表,将一个人的兴趣编号用并查集和并起来,这样有相同兴趣的人就被分在了一个组,然后遍历每一个人,查找他的兴趣的父亲节点,然后用一个计数数组技术便可以得到每个圈子有多少人,不为零的个数就是圈子个数
code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1010;
int pre[maxn];
int user[maxn];
int hobby[maxn];
int n;
void init(){
for(int i = 0; i < maxn; i++){
pre[i] = i;
}
}
int Find(int x){
if(x == pre[x])
return x;
else return pre[x] = Find(pre[x]);
}
void Merge(int x,int y){
int fx = Find(x),fy = Find(y);
if(fx != fy){
pre[fx] = fy;
}
}
bool cmp(int a,int b){
return a > b;
}
int main(){
init();
memset(hobby,0,sizeof(hobby));
cin >> n;
for(int i = 0; i < n; i++){
int k,h;
scanf("%d: ",&k);
cin >> h;
user[i] = h;
for(int j = 1; j < k; j++){
cin >> h;
Merge(user[i],h);
}
}
for(int i = 0; i < n; i++){
int id = Find(user[i]);
hobby[id]++;
}
int cnt = 0;
for(int i = 0; i < maxn; i++){
if(hobby[i])cnt++;
}
sort(hobby,hobby+maxn,cmp);
printf("%d\n",cnt);
for(int i = 0; i < cnt; i++){
printf("%d%c",hobby[i],i == cnt-1 ? '\n' : ' ');
}
return 0;
}