第三部分 数据结构 --第四章 图论算法-1389:亲戚

1389:亲戚

时间限制: 1000 ms 内存限制: 65536 KB
提交数: 3858 通过数: 1211
【题目描述】
若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的某个人所在家族的人数。

规定:x和y是亲戚,y和z是亲戚,那么x和z也是亲戚。如果x,y是亲戚,那么x的亲戚都是y的亲戚,y的亲戚也都是x的亲戚。

【输入】
第一行:三个整数n,(n≤100,000,m≤200,000),分别表示有n个人,m个信息。

以下m行:信息包含两种形式:

M a b:表示a和b具有亲戚关系。

Q a:要求输出a所在家族的人数。

【输出】
要求输出a所在家族的人数。

【输入样例】
5 10
M 3 2
Q 4
M 1 2
Q 4
M 3 2
Q 1
M 3 1
Q 5
M 4 2
Q 4
【输出样例】
1
1
3
1
4


思路:求a所在家族人数,我们将家族看成集合,如果两人是亲戚,就合并他们所在集合,询问即所求集合内元素的数量,用并查集解决该问题。增加一个数组记录集合内元素数量,用于求答案。

#include<cstdio>
#include<iostream>
#include<cstring>
#define N 100001
using namespace std;
int father[N];
int cnt[N];
int find(int x){//查找根节点
	if(father[x] == x)
	return x;
	return father[x] = find(father[x]);
}
void un(int x, int y){
	x = find(x);
	y = find(y);
	if(x != y){
		father[y] = x;
		cnt[x] += cnt[y];
	}
}

int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i = 1; i <= n; i++)
	{
		father[i] = i;//初始化集合
		cnt[i] = 1;
		
	}
	while(m--){
		char ch[10];
		scanf("%s",ch);
		if(ch[0] == 'M')
		{
			int a,b;
			scanf("%d%d",&a,&b);
			un(a,b);
		}
		if(ch[0] == 'Q')
		{
			int a;
			scanf("%d",&a);
			printf("%d\n",cnt[find(a)]);
		 } 
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章