zoukankan      html  css  js  c++  java
  • HDU 1269.迷宫城堡-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
    ",num==1?"Yes":"No");
    78     }
    79     return 0;
    80 }
  • 相关阅读:
    Tomcat7,Tomcat8 的manager 配置
    JavaScript 获得当前日期+时间
    CentOS 安装jdk 1.8
    nginx文件结构与解析,例子
    jxl解析多个excel工作表-java代码
    一个上传图片,预览图片的小demo
    利用DES,C#加密,Java解密代码
    CentOS安装Nginx
    摄像机标定--很懒的方法
    slam-g2o安装失败的解决问题
  • 原文地址:https://www.cnblogs.com/ZERO-/p/9114434.html
Copyright © 2011-2022 走看看