zoukankan      html  css  js  c++  java
  • 迷宫城堡(强联通targin)

    迷宫城堡

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 10409    Accepted Submission(s): 4674


    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
    题解:
    强联通问题,targin算法,或者dfs做,建图也可以用邻接表,或者vector;
    方法一dfs:
     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<math.h>
     4 #include<algorithm>
     5 #include<vector>
     6 using namespace std;
     7 #define MAX(x,y)(x>y?x:y)
     8 #define MIN(x,y)(x<y?x:y)
     9 //#define LOCAL
    10 const int INF=0x3f3f3f3f;
    11 const int MAXN=10010;
    12 vector<int>vec[MAXN];
    13 int vis[MAXN];
    14 void dfs(int x){
    15     for(int i=0;i<vec[x].size();i++){
    16         int v=vec[x][i];
    17         if(vis[v])continue;
    18         vis[v]=1;
    19         dfs(v);
    20     }
    21 }
    22 int main(){
    23     #ifdef LOCAL
    24     freopen("data.in","r",stdin);
    25     freopen("data.out","w",stdout);
    26     #endif
    27     int N,M;
    28     while(~scanf("%d%d",&N,&M),N|M){
    29         for(int i=0;i<MAXN;i++)vec[i].clear();
    30         while(M--){
    31             int a,b;
    32             scanf("%d%d",&a,&b);
    33             vec[a].push_back(b);
    34         }
    35         int ans=1;
    36         for(int i=1;i<=N;i++){
    37             memset(vis,0,sizeof(vis));
    38             vis[i]=1;
    39             dfs(i);
    40             for(int i=1;i<=N;i++){
    41                 if(vis[i]==0){
    42                     ans=0;
    43                     break;
    44                 }
    45                 if(!ans)break;
    46             }
    47             if(!ans)break;
    48         }
    49         if(ans)puts("Yes");
    50         else puts("No");
    51     }
    52     return 0;
    53 }

    方法二:targin算法:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<stack>
     7 #include<vector>
     8 #define mem(x,y) memset(x,y,sizeof(x))
     9 using namespace std;
    10 const int INF=0x3f3f3f3f;
    11 const int MAXN=10010;
    12 //#define LOCAL
    13 vector<int>vec[MAXN];
    14 stack<int>S;
    15 int dfn[MAXN],low[MAXN],Instack[MAXN];
    16 int scc,dfs_block;
    17 void targin(int u,int fa){
    18     dfn[u]=low[u]=++dfs_block;
    19     S.push(u);
    20     Instack[u]=1;
    21     for(int i=0;i<vec[u].size();i++){
    22         int v=vec[u][i];
    23         if(!dfn[v]){
    24             targin(v,u);
    25             low[u]=min(low[u],low[v]);
    26         }
    27         else if(Instack[v])
    28             low[u]=min(low[u],dfn[v]);
    29     }
    30     if(low[u]==dfn[u]){
    31         scc++;
    32         while(1){
    33         int v=S.top();
    34         S.pop();
    35         Instack[v]=0;
    36         if(u==v)break;
    37         }
    38     }
    39 }
    40 int main(){
    41     #ifdef LOCAL
    42     freopen("data.in","r",stdin);
    43     freopen("data.out","w",stdout);
    44     #endif
    45     int N,M;
    46     while(~scanf("%d%d",&N,&M),N|M){
    47         for(int i=0;i<MAXN;i++)vec[i].clear();
    48         mem(dfn,0);mem(low,0);mem(Instack,0);
    49         while(!S.empty())S.pop();
    50         int a,b;
    51         while(M--){
    52             scanf("%d%d",&a,&b);
    53             vec[a].push_back(b);
    54         }
    55         scc=dfs_block=0;
    56         for(int i=1;i<=N;i++){
    57             if(dfn[i])continue;
    58             targin(i,-1);
    59         }
    60         if(scc==1)puts("Yes");
    61         else puts("No");
    62     }
    63     return 0;
    64 }

     邻接表建图又写了一遍,邻接表都不太熟练了:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<stack>
     7 #include<vector>
     8 using namespace std;
     9 const int INF=0x3f3f3f3f;
    10 //#define LOCAL
    11 #define mem(x,y) memset(x,y,sizeof(x))
    12 const int MAXN=10010;
    13 const int MAXM=100010;//<<1;
    14 int head[MAXM],low[MAXN],dfn[MAXN],Instack[MAXN];
    15 int edgnum,dfs_block,lcc;
    16 stack<int>S;
    17 struct Edge{
    18     int from,to,next;
    19 };
    20 Edge edg[MAXM];
    21 void add(int u,int v){
    22     Edge E={u,v,head[u]};
    23     edg[edgnum]=E;
    24     head[u]=edgnum++;//**
    25 }
    26 void targin(int u,int fa){
    27         low[u]=dfn[u]=++dfs_block;
    28         S.push(u);
    29         Instack[u]=1;
    30         for(int i=head[u];i!=-1;i=edg[i].next){//**
    31             int v=edg[i].to;
    32             if(!dfn[v]){
    33                 targin(v,u);
    34                 low[u]=min(low[v],low[u]);
    35             }
    36             else if(Instack[v]){
    37                 low[u]=min(low[u],dfn[v]);
    38             }
    39         }
    40         if(low[u]==dfn[u]){
    41             lcc++;
    42             while(1){
    43             int v=S.top();
    44             S.pop();
    45             Instack[v]=0;
    46             if(u==v)break;
    47             }
    48         }
    49 }
    50 int main(){
    51     #ifdef LOCAL
    52     freopen("data.in","r",stdin);
    53     freopen("data.out","w",stdout);
    54     #endif
    55     int N,M;
    56     while(~scanf("%d%d",&N,&M),N|M){
    57     mem(head,-1);mem(dfn,0);mem(low,0);mem(Instack,0);
    58         edgnum=dfs_block=lcc=0;
    59         while(!S.empty())S.pop();
    60         int a,b;
    61         while(M--){
    62             scanf("%d%d",&a,&b);
    63             add(a,b);
    64         }
    65         for(int i=1;i<=N;i++){
    66             if(dfn[i])continue;
    67             targin(i,-1);
    68         }
    69         if(lcc==1)puts("Yes");
    70         else puts("No");
    71     }
    72     return 0;
    73 }
  • 相关阅读:
    【摄影】延时摄影
    【sas sql proc】统计
    【分析模板】excel or sas
    JavaScript的方法和技巧
    好书推荐
    七招制胜ASP.NET应用程序开发
    .Net中使用带返回值的存储过程(VB代码)
    ASP.NET 2.0构建动态导航的Web应用程序(TreeView和Menu )
    简单查询和联合查询两方面介绍SQL查询语句
    数字金额大小写转换之存储过程
  • 原文地址:https://www.cnblogs.com/handsomecui/p/4898514.html
Copyright © 2011-2022 走看看