[並查集]HOJ 2676 Relation

傳送門:Relation

Relation

My Tags   (Edit)
  Source : lilu0355
  Time limit : 1 sec   Memory limit : 64 M

Submitted : 793, Accepted : 273

若某個家族人員過於龐大,要判斷兩個是否是親戚,確實還很不容易,現在給出某個親戚關係圖,求任意給出的兩個人是否具有親戚關係。

規定:x和y是親戚,y和z是親戚,那麼x和z也是親戚。如果x,y是親戚,那麼x的親戚都是y的親戚,y的親戚也都是x的親戚。

Input

多組case,每組case中,第一行輸入N(1 ≤ N ≤ 5000),M(1 ≤ M ≤ 5000),Q(1 ≤ Q ≤ 5000),分別表示人數,關係數,詢問次數。

接着輸入M行,每行兩個整數a,b,表示a和b之間有親戚關係。

接着輸入Q行,每行兩個整數a,b,表示詢問a和b之間是否有親戚關係。

注:人的下標從1開始。

Output

爲每條詢問輸入一行,當有親戚關係時,輸出yes,否則輸出no.

Sample Input

5 2 3
1 2
2 3
1 3
2 4
3 5

Sample Output

yes
no
no

解題報告:

基礎並查集。代碼如下:

#include<iostream>
#include<cstdio>
using namespace std;
int father[5005],num[5005];
int n,m,q;
void makeset(int n){
    for(int j=1;j<=n;j++){
        father[j]=j;
        num[j]=1;
    }
}
int findset(int x){
    return father[x]==x?x:father[x]=findset(father[x]);
}
void Union(int a,int b){
    int x=findset(a);
    int y=findset(b);
    if(x==y)
        return;
    if(num[x]<=num[y]){
        father[x]=y;
        num[y]+=num[x];
    }
    else{
        father[y]=x;
        num[x]+=num[y];
    }
}
int main(){
    int t=0;
    while(scanf("%d%d%d",&n,&m,&q)==3){
        makeset(n);
        int a,b;
        for(int i=0;i<m;i++){
            scanf("%d%d",&a,&b);
            Union(a,b);
        }
        for(int i=0;i<q;i++){
            scanf("%d%d",&a,&b);
            findset(a)==findset(b)?puts("yes"):puts("no");
        }
    }
    return 0;
}


發佈了168 篇原創文章 · 獲贊 3 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章