PAT(甲级)1107 Social Clusters(并查集)

Description

题目大意:寻找相同爱好的朋友圈

Input

一个正整数N,代表N个人
接下来N行:Ki hi[1]…hi[n]代表第i个人有k个爱好,爱好下标分别是hi[j] (1<=j<=k)

Output

第一行输出有多少个朋友圈
第二行按照从大到小输出每个朋友圈人数(注意空格)

解题思路

算法标签:并查集
将具有同一爱好的人合并,如果subsets[i].num为0,说明此时爱好I目前还没有人,那么初始化为这个第一个具有此爱好的人,然后与有这个同样爱好的人
最后用count_root统计根节点的个数,个数即为朋友圈个数,再排序输出

代码

//freopen("hao.txt","r",stdin);
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 1005;

struct Subset
{
	int parent;
	int rank;
	// 喜欢该活动人的编号
	int num;
}subsets[N];

bool cmp(int a,int b)
{
	return a>b;
}
int find(int x)
{
	if(subsets[x].parent!=x)
		subsets[x].parent = find(subsets[x].parent);

	return subsets[x].parent;
}

void Union(int x,int y)
{
	int x_root = find(x);
	int y_root = find(y);

	if(x_root==y_root)
		return;

	if(subsets[x_root].rank < subsets[y_root].rank){
		subsets[x_root].parent = y_root;
	}
	else if(subsets[x_root].rank < subsets[y_root].rank)
		subsets[y_root].parent = x_root;
	else {
		subsets[x_root].parent = y_root;
		subsets[y_root].rank++;
	}
}

int main()
{
	int n = 0,m = 0;
	int x =0;
	int ans = 0;
	int count_root[N] = {0};
	cin>>n;

	for(int i=1;i<=1000;i++) {
		subsets[i].parent = i;
		subsets[i].rank = 0;
		subsets[i].num = 0;
	}
	for(int i=1;i<=n;i++) {
		cin>>m;
		getchar();
		for(int j=1;j<=m;j++){
			cin>>x;
			if(subsets[x].num==0){
				subsets[x].num = i;
			}
			Union(i,find(subsets[x].num));
		}
	}

	for(int i=1;i<=n;i++)
		count_root[find(i)]++;

	sort(count_root+1,count_root+n+1,cmp);

	for(int i=1;i<=n;i++)
		if(count_root[i]!=0)
			ans++;

	cout<<ans<<endl;
	for(int i=1;i<=ans;i++){
		if(i!=1)
			cout<<" "<<count_root[i];
		else
			cout<<count_root[i];
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值