• 迷宫城堡--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 }
  • 相关阅读:
    JPA的一对多,多对多用法
    pg数据库中时间查询的方式
    DNS消息格式
    Netty之Java堆外内存扫盲贴
    Netty writeAndFlush() 流程与异步
    Netty之有效规避内存泄漏
    TCP状态变迁图
    TCP/IP详解--发送ACK和RST的场景
    TCP/IP详解--连接状态变迁图CLOSE_WAIT
    TCP中异常关闭链接的意义 异常关闭的情况
  • 原文地址:https://www.cnblogs.com/anhuizhiye/p/3460809.html
Copyright © 2020-2023  润新知