第三部分 數據結構 -- 第四章 圖論算法-1346:【例4-7】親戚(relation)

1346:【例4-7】親戚(relation)

時間限制: 1000 ms 內存限制: 65536 KB
提交數: 14138 通過數: 2701
【題目描述】
或許你並不知道,你的某個朋友是你的親戚。他可能是你的曾祖父的外公的女婿的外甥女的表姐的孫子。如果能得到完整的家譜,判斷兩個人是否是親戚應該是可行的,但如果兩個人的最近公共祖先與他們相隔好幾代,使得家譜十分龐大,那麼檢驗親戚關係實非人力所能及。在這種情況下,最好的幫手就是計算機。爲了將問題簡化,你將得到一些親戚關係的信息,如Marry和Tom是親戚,Tom和Ben是親戚,等等。從這些信息中,你可以推出Marry和Ben是親戚。請寫一個程序,對於我們的關於親戚關係的提問,以最快的速度給出答案。

【輸入】
輸入由兩部分組成。

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

第二部分以Q開始。以下Q行有Q個詢問(1≤ Q ≤1000000),每行爲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


思路:這是一道並查集的題目,我們首先將所有人的父節點設爲自己,如果一對父子的父節點不相同則調用並集函數,在查找時,如果兩者父節點相同證明他們兩是親戚,否則不是。

#include<iostream>
#include<cstdio>
#include<cstdlib>

using namespace std;
int father[20005];
inline void scanf_(int &num)
{
    char in=getchar(); num=0;
    while(in>'9'||in<'0')in=getchar();
    while(in>='0'&&in<='9'){num*=10;num+=in-'0';in=getchar();}
}
int find_father(int x){
int temp=x,a;
while(father[x]!=x)
    x=father[x];
while(father[temp]!=temp){
    a=temp;
    temp=father[temp];
father[temp]=x;
}
return x;
}
void union_(int x,int y){
int xx=find_father(x);
int yy=find_father(y);
if(xx!=yy)
    father[xx]=yy;
}
int main(){
    int re,n,a,b;
    scanf_(re);scanf_(n);
    for(int i=1;i<=re;i++)father[i]=i;
    for(int i=1;i<=n;i++)
    {
        scanf_(a);scanf_(b);
        union_(a,b);
    }
    int q;
    scanf_(q);
    while(q--){
        scanf_(a);scanf_(b);
        if(find_father(a)==find_father(b))printf("Yes\n");
        else printf("No\n");
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章