zoukankan      html  css  js  c++  java
  • 迷宫城堡--HDOJ 1269(Tarjan)

    迷宫城堡

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


    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
    思路:tarjan算法,很好的一个想法和思路,只需要对全图进行一次DFS 就行。
    AC代码:
     1 /*=====================================================================
     2 # Author: wangzhili
     3 # Mail  : wangstdio.h@gmail.com
     4 # QQ : 240130760
     5 # Filename: tarjan.c
     6 # Last modified: 2013-12-06 09:18
     7 =====================================================================*/
     8 
     9 #include<stdio.h>
    10 #include<string.h>
    11 typedef struct
    12 {
    13     int to;
    14     int next;
    15 }EdgeNode;
    16 EdgeNode edge[100005];
    17 int dfn[10005],low[10005];
    18 int head[10005],vis[10005];
    19 int stack[10005];
    20 int top,ind,cnt,n,m;
    21 int min(int x,int y)
    22 {
    23     return x < y ? x : y;
    24 }
    25 
    26 void tarjan(int i)
    27 {
    28     int j,v;
    29     dfn[i] = low[i] = ++ind;
    30     stack[++top] = i;
    31     vis[i] = 1;
    32     for(j = head[i]; j != -1;j = edge[j].next)
    33     {
    34         v = edge[j].to;
    35         if(!dfn[v])
    36         {
    37             tarjan(v);
    38             low[i] = min(low[i],low[v]);
    39         }
    40         else if(vis[v])
    41             low[i] = min(low[i],dfn[v]);
    42     }
    43     if(dfn[i] == low[i])
    44     {
    45         cnt ++;
    46         do
    47         {
    48             j = stack[top--];
    49             vis[j] = 0;
    50         }while(j != i);
    51     }
    52 }
    53 void solve()
    54 {
    55     int i;
    56     cnt = 0;
    57     top = ind = 0;
    58     memset(dfn,0,sizeof(dfn));
    59     memset(vis,0,sizeof(vis));
    60     for(i = 1;i <= n;i ++)
    61     {
    62         if(!dfn[i])
    63             tarjan(i);
    64     }
    65     return ;
    66 }
    67 
    68 int main()
    69 {
    70     int i,j;
    71     int a,b;
    72     freopen("in.c","r",stdin);
    73     while(~scanf("%d%d",&n,&m) && (m+n))
    74     {
    75         memset(head,-1,sizeof(head));
    76         for(i = 0;i < m;i ++)
    77         {
    78             scanf("%d%d",&a,&b);
    79             edge[i].to = b;
    80             edge[i].next = head[a];
    81             head[a] = i;
    82         }
    83         solve();
    84         if(cnt == 1)
    85             printf("Yes
    ");
    86         else
    87             printf("No
    ");
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    JS数组存储(两个数组相等,一个改变,另一个跟着改变)
    图片404加载失败后如何处理
    为什么重写equals方法,还必须要重写hashcode方法
    Java中HashMap和TreeMap的区别深入理解
    java中String数组和List的互相转化
    log4j重复打印的解决方法
    mysql 允许在唯一索引的字段中出现多个null值
    elasticsearch 常见查询及聚合的JAVA API
    A记录(主机名解析)、CNAME(别名解析)和URL转发(域名转发)
    域名解析中的cname解析和显性URL跳转和隐性URL跳转三者有什么区别
  • 原文地址:https://www.cnblogs.com/anhuizhiye/p/3460809.html
Copyright © 2011-2022 走看看