1. 程式人生 > >小鑫的城堡

小鑫的城堡

ID 連通 AC .cn print 兩個 設計圖 span 數組

從前有一個國王,他叫小鑫。有一天,他想建一座城堡,於是,設計師給他設計了好多簡易圖紙,主要是房間的連通的圖紙。小鑫希望任意兩個房間有且僅有一條路徑可以相通。小鑫現在把設計圖給你,讓你幫忙判斷設計圖是否符合他的想法。比如下面的例子,第一個是符合條件的,但是,第二個不符合,因為從5到4有兩條路徑(5-3-4和5-6-4)。
技術分享圖片技術分享圖片

Input

多組輸入,每組第一行包含一個整數m(m < 100000),接下來m行,每行兩個整數,表示了一條通道連接的兩個房間的編號。房間的編號至少為1,且不超過100000。

Output

每組數據輸出一行,如果該城堡符合小鑫的想法,那麽輸出"Yes",否則輸出"No"。

Sample Input

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

Sample Output

Yes
No

由題目"任意兩個房間有且僅有一條路徑可以相通"可知,不能成環並且所有給出的點必須相連,則可推:所給邊的數量要等於所給點的數量減1。
用並查集判斷是否成環。
用hash表記錄所給點數。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#define Maxn 100020
using
namespace std; char parent[Maxn]; bool ha[Maxn]; int flag; int Find(int x) { int r,temp; for(r=x; parent[r]>=0; r=parent[r]); while(r!=x) { temp=x; x=parent[x]; parent[temp]=r; } return r; } void merge(int A,int B) { int a=Find(A),b=Find(B);
if(a==b) flag=1; else { int temp=parent[a]+parent[b]; if(parent[a]>parent[b]) { parent[a]=b; parent[b]=temp; } else { parent[b]=a; parent[a]=temp; } } } int main() { int n; while(scanf("%d",&n)!=EOF) { int a,i,b,m=0; flag=0; memset(ha,0,sizeof(ha)); memset(parent,-1,sizeof(parent)); for(i=0; i<n; i++){ scanf("%d%d",&a,&b); if(ha[a]==0){ ha[a]=1; m++; } if(ha[b]==0){ ha[b]=1; m++; } merge(a,b); } if(m-1==n && !flag) printf("Yes\n"); else printf("No\n"); } return 0; }

(測試證明,memset對bool型數組也適用)

小鑫的城堡