7-90 社交集群 (30分)--详解

7-90 社交集群 (30分)

当你在社交网络平台注册时,一般总是被要求填写你的个人兴趣爱好,以便找到具有相同兴趣爱好的潜在的朋友。一个“社交集群”是指部分兴趣爱好相同的人的集合。你需要找出所有的社交集群。

在这里插入图片描述

输出格式:
首先在一行中输出不同的社交集群的个数。随后第二行按非增序输出每个集群中的人数。数字间以一个空格分隔,行末不得有多余空格。

输入样例:
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

思路
开始把问题想复杂了。其实直接可以:每一个人用第一个兴趣编号作为代表,将一个人的兴趣编号用并查集和并起来,这样有相同兴趣的人就被分在了一个组,然后遍历每一个人,查找他的兴趣的父亲节点,然后用一个计数数组技术便可以得到每个圈子有多少人,不为零的个数就是圈子个数。

#include<bits/stdc++.h>
using namespace std;
int p[1009], user[1009], hobby[1009]; 

int find(int x){  //找祖先 
	if(p[x] == x){
		return x;
	}
	return p[x] = find(p[x]);
}

void merge(int x, int y){  //合并 
	int xx = find(x), yy = find(y);
	if(xx != yy){
		p[yy] = xx;
	}
}

bool cmp(int x, int y){  //因为题目说非曾序,所以两个数相等时不用交换顺序 
	return x > y;
}

int main()
{
	for(int i=1; i<=1000; i++){
		p[i] = i;
	}
	int n,k,h,num=0;
	char ch;
	cin >> n;
	for(int i=1; i<=n; i++){
		cin >> k >> ch >> user[i]; //user[i]:用第一个兴趣来代表每一个人 
		for(int j=1; j<=k-1; j++){
			cin >> h;
			merge(user[i], h);
		}
	}
	for(int i=1; i<=n; i++){
		hobby[find(user[i])]++;  //计算每个圈子多少人 
	}
	for(int i=1; i<=1000; i++){
		if(hobby[i]!=0) num++;  //统计圈子个数 
	}
	sort(hobby, hobby+1001, cmp);
	cout << num << endl;
	for(int i=0; i<num; i++){
		if(i!=0) cout << " ";
		cout << hobby[i];
	}
	return 0;
}
发布了39 篇原创文章 · 获赞 2 · 访问量 3441

猜你喜欢

转载自blog.csdn.net/weixin_43581819/article/details/103897801