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
[csharp]
#include<stdio.h>
#include<string.h>
int farth[100005],ran[100005],use[100005],t,n,m,flog,k;
void first_set()
{
int i;
for(i=0;i<=100000;i++)
farth[i]=i; //開始每一個父節點是其本身
memset(ran,0,sizeof(ran));//表示集合的大小
memset(use,0,sizeof(use));//表示當前的點是否存在,1表示存在
}
int find_first_Farth(int x)//找出當前點x的最原始的父節點
{
//printf("%dx %df ",x,farth[x]);
while(x!=farth[x])
x=farth[x];
//farth[x]=find_first_Farth(farth[x]);
return x;
}
int uion(int x,int y)
{
x=find_first_Farth(x);//找出x的最終父結點;最開始時父結點是其本身
y=find_first_Farth(y);//找了y的最終父結點
if(x==y)//說明形成了一個環
return 0;
if(ran[x]<ran[y])//把x所在的小集合,合並到y所在的大集合裡面去
farth[x]=y;
else
{
if(ran[x]==ran[y])//把同等級的集合 合並到一個集合裡
ran[x]++;
farth[y]=x;
}
return 1;
}
int main()
{
while(scanf("%d%d",&n,&m)>0)
{
first_set();
flog=1;
if(n==-1&&m==-1)
break;
uion(n,m);
use[n]=1;use[m]=1;
k=1;
if(n!=0||m!=0)
while(scanf("%d%d",&n,&m)>0)
{
if(n==0&&m==0)
break;
if(use[n]==0)
{
k++;use[n]=1;//1表示n的這個點己經存在了
}
if(use[m]==0)
{
k++;use[m]=1;
}
if(uion(n,m)==0)
flog=0;
else
k--;//記錄點和邊的差值
}
printf("%s\n",(flog!=0&&k==1)?"Yes":"No");
}
}
/*1 2 3 4 0 0 N0*///這種情況的話,雖沒有形成環,但是是兩個不相干的直線
#include<stdio.h>
#include<string.h>
int farth[100005],ran[100005],use[100005],t,n,m,flog,k;
void first_set()
{
int i;
for(i=0;i<=100000;i++)
farth[i]=i; //開始每一個父節點是其本身
memset(ran,0,sizeof(ran));//表示集合的大小
memset(use,0,sizeof(use));//表示當前的點是否存在,1表示存在
}
int find_first_Farth(int x)//找出當前點x的最原始的父節點
{
//printf("%dx %df ",x,farth[x]);
while(x!=farth[x])
x=farth[x];
//farth[x]=find_first_Farth(farth[x]);
return x;
}
int uion(int x,int y)
{
x=find_first_Farth(x);//找出x的最終父結點;最開始時父結點是其本身
y=find_first_Farth(y);//找了y的最終父結點
if(x==y)//說明形成了一個環
return 0;
if(ran[x]<ran[y])//把x所在的小集合,合並到y所在的大集合裡面去
farth[x]=y;
else
{
if(ran[x]==ran[y])//把同等級的集合 合並到一個集合裡
ran[x]++;
farth[y]=x;
}
return 1;
}
int main()
{
while(scanf("%d%d",&n,&m)>0)
{
first_set();
flog=1;
if(n==-1&&m==-1)
break;
uion(n,m);
use[n]=1;use[m]=1;
k=1;
if(n!=0||m!=0)
while(scanf("%d%d",&n,&m)>0)
{
if(n==0&&m==0)
break;
if(use[n]==0)
{
k++;use[n]=1;//1表示n的這個點己經存在了
}
if(use[m]==0)
{
k++;use[m]=1;
}
if(uion(n,m)==0)
flog=0;
else
k--;//記錄點和邊的差值
}
printf("%s\n",(flog!=0&&k==1)?"Yes":"No");
}
}
/*1 2 3 4 0 0 N0*///這種情況的話,雖沒有形成環,但是是兩個不相干的直線