第三部分 數據結構 --第四章 圖論算法-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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章