(並查集 不太會) HDU 1272 小希的迷宮

Problem Description
上次Gardon的迷宮城堡小希玩了好久(見Problem B),如今她也想設計一個迷宮讓Gardon來走。可是她設計迷宮的思路不同,首先她認爲全部的通道都應該是雙向連通的,就是說若是有一個通道連通了房間A和B,那麼既能夠經過它從房間A走到房間B,也能夠經過它從房間B走到房間A,爲了提升難度,小希但願任意兩個房間有且僅有一條路徑能夠相通(除非走了回頭路)。小希如今把她的設計圖給你,讓你幫忙判斷她的設計圖是否符合她的設計思路。好比下面的例子,前兩個是符合條件的,可是最後一個卻有兩種方法從5到達8。 
 

 

Input
輸入包含多組數據,每組數據是一個以0 0結尾的整數對列表,表示了一條通道鏈接的兩個房間的編號。房間的編號至少爲1,且不超過100000。每兩組數據之間有一個空行。 
整個文件以兩個-1結尾。
 

 

Output
對於輸入的每一組數據,輸出僅包括一行。若是該迷宮符合小希的思路,那麼輸出"Yes",不然輸出"No"。
 

 

Sample Input
6 8   5 3   5 2  6 4 
5 6   0 0
 
8 1  7 3  6 2  8 9  7 5 
7 4  7 8  7 6 0 0
 
3 8  6 8  6 4
5 3  5 6 5 2  0 0
 
-1 -1
 

 

Sample Output
Yes
Yes
No
 
 
這個是並查集,不過,卻花了我很長時間才過。這個是要判斷這個圖中是否有環,若是有,那就輸出No,若是沒有,繼續接下來的判斷,而後,判斷最後獲得的並查集的個數,若是是一個,就輸出Yes,不然輸出No。另外,這個不太不須要壓縮路徑,加了就錯emmmmmm。
 
C++代碼:
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 100010;
int father[maxn],vis[maxn];
int flag = 0; 
int Find(int x){
    while(x != father[x]){
//        father[x] = father[father[x]];
        x = father[x];
    }
    return x;
}
void Union(int a,int b){
    int ax = Find(a);
    int bx = Find(b);
    if(ax != bx)
        father[ax] = bx;
    else
        flag = 0;
}
int main(){
    int a,b;
    while(cin>>a>>b){
        if(a == -1 && b == -1)
            break;
        if(a == 0 && b == 0){
            cout<<"Yes"<<endl;
            continue;
        }
        for(int i = 1; i < maxn; i++){
            father[i] = i;
            vis[i] = 0;
        }
        vis[a] = vis[b] = 1;
        flag = 1;
        Union(a,b);
        while(cin>>a>>b){
            if(a == 0 && b == 0) break;
            vis[a] = vis[b] = 1;
            Union(a,b);
        }
        int sum = 0;
        for(int i = 1; i < maxn; i++){
            if(vis[i] && father[i] == i)
                sum++;
            
            if(sum > 1){
                flag = 0;
                break;
            }
        }
        if(flag == 1) puts("Yes");
        else puts("No");
    }
    return 0;
}
相關文章
相關標籤/搜索