【题解】【AcWing】1597. 社会集群

145 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1597. 社会集群

原题传送:AcWing 1597. 社会集群

在一些社交网络平台上注册账号时,平台总是会要求你填写自己的兴趣爱好,以便找到一些具有相同兴趣爱好的潜在朋友。

社会集群是指一群有共同爱好的人。

给定社交网络中所有人的兴趣爱好,请你找到所有社会群集。

输入格式

第一行包含一个正整数 NN ,表示社交网络的人数。

所有人的编号为 1N1 \sim N

接下来 NN 行,每行包含一个人的爱好信息,格式如下:

Ki:K_i: hi[1]h_i[1] hi[2]h_i[2]hi[Ki]h_i[K_i]

KiK_i 表示爱好数量, hi[j]h_i[j] 表示第 jj 个爱好的编号。

输出格式

第一行输出总集群数量。

第二行按非递增顺序输出每个集群的人数。

数字之间空格隔开,行尾不得有多余空格。

数据范围

1N10001 \le N \le 1000 , Ki>0K_i>0 , 爱好种类最多 10001000 种,编号范围 [1,1000][1,1000]

输入样例:

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

样例解释

33 个集群:

  • 44 人集群 {2,4,6,8}\lbrace2,4,6,8\rbrace ,他们都有共同的爱好 44
  • 33 人集群 {3,5,7}\lbrace3,5,7\rbrace ,其中 3355 有共同的爱好 333377 有共同的爱好 55
  • 11 人集群 {1}\lbrace1\rbrace

思路:

将各种爱好对应的人存入vector,然后遍历每种爱好,将同一种爱好的人合并至一个集合,最后统计集合的数量和每个集合的人数。

题解:

#include <bits/stdc++.h>

using namespace std;

const int N = 1010;

int n;
vector<int> hobby[N];
int p[N];
int cnt[N];

int find(int x)
{
	if(p[x] != x)
		p[x] = find(p[x]);
	return p[x];
}

int main()
{
	scanf("%d", &n);
	
	for(int i = 0; i < n; i++)
		p[i] = i;
		
	for(int i = 0; i < n; i++)
	{
		int cnt;
		scanf("%d:", &cnt);
		
		while(cnt--)
		{
			int h;
			scanf("%d", &h);
			hobby[h].push_back(i);
		}
	}
		
	for(int i = 0; i < N; i++)
	{
		for(int j = 1; j < hobby[i].size(); j++)
		{
			int a = hobby[i][0], b = hobby[i][j];
			p[find(a)] = find(b);
		}
	}
	
	for(int i = 0; i < n; i++)
		cnt[find(i)]++;
	
	sort(cnt, cnt + n, greater<int>());
	
	int k = 0;
	while(cnt[k])
		k++;
		
	printf("%d\n", k);
	printf("%d", cnt[0]);
	for(int i = 1; i < k; i++)
		printf(" %d", cnt[i]);
	printf("\n"); 
	
	return 0;
}