親戚B (普通並查集)

描述

或許你並不知道,你的某個朋友是你的親戚。他可能是你的曾祖父的外公的女婿的外甥女的表姐的孫子。如果能得到完整的家譜,判斷兩個人是否是親戚應該是可行的,但如果兩個人的最近公共祖先與他們相隔好幾代,使得家譜十分龐大,那麼檢驗親戚關係實非人力所能及。

在這種情況下,最好的幫手就是計算機。爲了將問題簡化,你將得到一些親戚關係的信息,如Marry和Tom是親戚,Tom和Ben是親戚,等等。從這些信息中,你可以推出Marry和Ben是親戚。請寫一個程序,對於我們的關於親戚關係的提問,以最快的速度給出答案。

格式

輸入格式

第一部分以N,M開始。N爲問題涉及的人的個數(1≤N≤1000)。這些人的編號爲1,2,3,…, N。下面有M行(1≤M≤1000),每行有兩個數ai,bi,表示已知ai和bi是親戚。

第二部分以Q開始。以下Q行有Q個詢問(1≤ Q ≤500),每行爲ci,di,表示詢問ci和di是否爲親戚。

輸出格式

對於每個詢問ci,di,輸出一行:若ci和di爲親戚,則輸出“Yes”,否則輸出“No”。

樣例

輸入樣例

10 7
2 4
5 7
1 3
8 9
1 2
5 6
2 3
3
3 4
7 10
8 9

輸出樣例

Yes
No
Yes

限制

時間限制: 1000 ms

內存限制: 65536 KB

注意:link函數中如果寫relative[a] = b;的話,只過30%,原因看下圖,圖和例子來自他人博客

void link(int a, int b) {
	int fa = findRelative(a);
	int fb = findRelative(b);
	if (fa != fb) {
		relative[fb] = fa;    //注意這裏是fa與fb,而不是a與b,若晚輩相連,則會出現找不到祖宗的情況
	}
}

該圖中,SHT與TPY是各自家族的祖宗,若LDB與WRY是親戚,直接相連,由findFather()函數的壓縮路徑的性質決定,找LC的親戚時,往上只能找到TPY,不能證明LC與SHT與親戚關係。而將SHT與TPY相連,則能實現找LC的親戚時,往上能找到SHT,從而證明他們有親戚關係。

下面試AC代碼

#include <bits/stdc++.h>
using namespace std;

int relative[1005];

int findRelative(int f) {
	if (relative[f] != f) {
		relative[f] = findRelative(relative[f]);
	}
	return relative[f];
}

void link(int a, int b) {
	int fa = findRelative(a);
	int fb = findRelative(b);
	if (fa != fb) {
		relative[fb] = fa;    
	}
}

int main(){
	int n, m, q, a, b;
	scanf ("%d %d", &n, &m);
	for (int i=1; i<=n; i++) {
		relative[i] = i;
	}
	for (int i=0; i<m; i++) {
		scanf ("%d %d", &a, &b);
		link(a, b);
	}
	scanf ("%d", &q);
	for (int i=0; i<q; i++) {
		scanf ("%d %d", &a, &b);
		int fa = findRelative(a);
		int fb = findRelative(b);
		if (fa == fb) {
			printf ("Yes\n");
		} else {
			printf ("No\n");
		}
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章