標籤:
迷宮城堡
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Problem Description為了訓練小希的方向感,Gardon建立了一座大城堡,裡面有N個房間(N<=10000)和M條通道(M<=100000),每個通道都是單向的,就是說若稱某通道連通了A房間和B房間,只說明可以通過這個通道由A房間到達B房間,但並不說明通過它可以由B房間到達A房間。Gardon需要請你寫個程式確認一下是否任意兩個房間都是相互連通的,即:對於任意的i和j,至少存在一條路徑可以從房間i到房間j,也存在一條路徑可以從房間j到房間i。
Input輸入包含多組資料,輸入的第一行有兩個數:N和M,接下來的M行每行有兩個數a和b,表示了一條通道可以從A房間來到B房間。檔案最後以兩個0結束。
Output對於輸入的每組資料,如果任意兩個房間都是相互串連的,輸出"Yes",否則輸出"No"。
Sample Input3 31 22 33 13 31 22 33 20 0
Sample OutputYesNo
AuthorGardon
SourceHDU 2006-4 Programming Contest思路:最後belong所有點都為一個值則輸出Yes; 否則輸出No;(晚上看的縮點,明天開始看tarjan,洗洗睡吧) 縮點演算法推薦:http://wenku.baidu.com/link?url=H6iQDzfiDht9cv8kyu0AjrpwDE6zxBKJKpGP-c1pqN2Uih1g9JzRuyw5cDanF76FNpUPg0WmqQW99VPcwDRcoT2qsGkrQ-aKFRdGpL6XfZm
#include<iostream>#include<cstdio>#include<cmath>#include<string>#include<queue>#include<algorithm>#include<stack>#include<cstring>#include<vector>#include<list>#include<set>#include<map>using namespace std;#define ll __int64#define inf 2000000001int scan(){ int res = 0 , ch ; while( !( ( ch = getchar() ) >= ‘0‘ && ch <= ‘9‘ ) ) { if( ch == EOF ) return 1 << 30 ; } res = ch - ‘0‘ ; while( ( ch = getchar() ) >= ‘0‘ && ch <= ‘9‘ ) res = res * 10 + ( ch - ‘0‘ ) ; return res ;}struct is{ int u,v; int next;}edge1[100010],edge2[100010];int flag1[10010],flag2[10010];int jiedge1,jiedge2;int jidian1,jidian2;int head1[100010],head2[100010];int shun1[100010],shun2[100010];int belong[100010];int n,m;void update(int x,int y){ jiedge1++; edge1[jiedge1].u=x; edge1[jiedge1].v=y; edge1[jiedge1].next=head1[x]; head1[x]=jiedge1; jiedge2++; edge2[jiedge2].u=y; edge2[jiedge2].v=x; edge2[jiedge2].next=head2[x]; head2[x]=jiedge2;}void dfs1(int x){ flag1[x]=1; for(int i=head1[x];i;i=edge1[i].next) { if(!flag1[edge1[i].u]) dfs1(edge1[i].u); } shun1[++jidian1]=x;}void dfs2(int x){ flag2[x]=1; belong[x]=jidian2; for(int i=head2[x];i;i=edge2[i].next) { if(!flag2[edge2[i].u]) dfs2(edge2[i].u); }}void Kosaraju(){ memset(flag1,0,sizeof(flag1)); memset(flag2,0,sizeof(flag2)); jidian1=0; for(int i=1;i<=n;i++) if(!flag1[i]) dfs1(i); jidian2=1; for(int i=jidian1;i>0;i--) { if(!flag2[i]) { dfs2(shun1[i]); jidian2++; } }}int main(){ int i; while(~scanf("%d%d",&n,&m)) { memset(head1,0,sizeof(head1)); memset(head2,0,sizeof(head2)); if(n==0&&m==0)break; jiedge1=0; jiedge2=0; for(i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); update(u,v); } Kosaraju(); /*for(i=1;i<=n;i++) cout<<belong[i]<<" "; cout<<endl;*/ int lu=0,ans=belong[1]; for(i=2;i<=n;i++) if(belong[i]!=ans) { lu=1; break; } if(lu) printf("No\n"); else printf("Yes\n"); } return 0;}View Code
hdu 1269 迷宮城堡 最簡單的聯通圖題 縮點演算法