HDU1269.迷宫城堡-Tarjan or 双向DFS
Posted Persistent.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU1269.迷宫城堡-Tarjan or 双向DFS相关的知识,希望对你有一定的参考价值。
迷宫城堡
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 20476 Accepted Submission(s): 8917
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 Input
3 3
1 2
2 3
3 1
3 3
1 2
2 3
3 2
0 0
Sample Output
Yes
No
Author
Gardon
Source
代码1:Tarjan
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<stack> 5 using namespace std; 6 const int N=1e5+10; 7 stack<int>sta; 8 vector<int>gra[N]; 9 int dfn[N],low[N],InStack[N]; 10 vector<int>Component[N]; 11 int InComponent[N]; 12 int index,ComponentNumber; 13 int n,m; 14 void init(){ 15 memset(dfn,0,sizeof(dfn)); 16 memset(low,0,sizeof(low)); 17 memset(InStack,0,sizeof(InStack)); 18 index=ComponentNumber=0; 19 for(int i=1;i<=n;i++){ 20 gra[i].clear(); 21 Component[i].clear(); 22 } 23 while(!sta.empty()) 24 sta.pop(); 25 } 26 void tarjan(int u){ 27 InStack[u]=2; 28 low[u]=dfn[u]=++index; 29 sta.push(u); 30 for(int i=0;i<gra[u].size();++i){ 31 int t=gra[u][i]; 32 if(dfn[t]==0){ 33 tarjan(t); 34 low[u]=min(low[u],low[t]); 35 } 36 else if(InStack[t]==2){ 37 low[u]=min(low[u],dfn[t]); 38 } 39 } 40 if(low[u]==dfn[u]){ 41 ++ComponentNumber; 42 while(!sta.empty()){ 43 int j=sta.top(); 44 sta.pop(); 45 InStack[j]=1; 46 Component[ComponentNumber].push_back(j); 47 InComponent[j]=ComponentNumber; 48 if(j==u)break; 49 } 50 } 51 } 52 void input(){ 53 for(int i=1;i<=m;i++){ 54 int a,b; 55 scanf("%d%d",&a,&b); 56 gra[a].push_back(b); 57 } 58 } 59 void solve(){ 60 for(int i=1;i<=n;i++) 61 if(!dfn[i])tarjan(i); 62 if(ComponentNumber>1)puts("No"); 63 else puts("Yes"); 64 } 65 int main(){ 66 while(scanf("%d%d",&n,&m),n+m){ 67 init(); 68 input(); 69 solve(); 70 } 71 return 0; 72 }
代码2:双向DFS
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<vector> 7 using namespace std; 8 const int maxn = 10000 + 5; 9 vector<int> node[maxn]; 10 vector<int> reverse_node[maxn]; 11 vector<int> reverse_post; 12 int marked[maxn]; 13 int N,M; 14 15 void reverse_dfs(int v){ 16 marked[v] = 1; 17 for(int w=0;w<reverse_node[v].size();w++){ 18 int to = reverse_node[v][w]; 19 if(!marked[to]){ 20 //cout<<"dfs="<<to<<endl; 21 reverse_dfs(to); 22 } 23 } 24 //cout<<"post in="<<v<<endl; 25 reverse_post.push_back(v); 26 } 27 28 void get_reverse(){ 29 reverse_post.clear(); 30 for(int v=1;v<=N;v++){ 31 if(!marked[v]){ 32 //cout<<"start="<<v<<endl; 33 reverse_dfs(v); 34 } 35 } 36 } 37 38 void dfs(int v){ 39 marked[v] = 1; 40 for(int w=0;w<node[v].size();w++){ 41 int to = node[v][w]; 42 if(!marked[to])dfs(to); 43 } 44 } 45 46 int main(){ 47 while(cin>>N>>M){ 48 if(N+M==0) break; 49 for(int i=1;i<=N;i++){ 50 node[i].clear(); 51 reverse_node[i].clear(); 52 marked[i]=0; 53 } 54 for(int i=0;i<M;i++){ 55 int a,b; 56 scanf("%d%d",&a,&b); 57 node[a].push_back(b); 58 reverse_node[b].push_back(a); 59 } 60 get_reverse(); 61 for(int i=1;i<=N;i++){ 62 marked[i] = 0; 63 } 64 int num=0; 65 for(int i=reverse_post.size()-1;i>=0;i--){ 66 int to = reverse_post[i]; 67 if(!marked[to]){ 68 //cout<<"again dfs="<<to<<endl; 69 if(num==1){ 70 num=2; 71 break; 72 } 73 dfs(to); 74 num++; 75 } 76 } 77 printf("%s\n",num==1?"Yes":"No"); 78 } 79 return 0; 80 }
以上是关于HDU1269.迷宫城堡-Tarjan or 双向DFS的主要内容,如果未能解决你的问题,请参考以下文章