zoukankan      html  css  js  c++  java
  • HDU1269迷宫城堡(裸Tarjan有向图求强连通分量个数)

    迷宫城堡Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 13833    Accepted Submission(s): 6174


    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
     
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<stack>
    #include<algorithm>
    using namespace std;
     
    #define N 10003
    int dfn[N],low[N],ins[N],Time,num;//ins是否在栈里
    vector<int>gra[N];
    stack<int>sta;
     
    void Tarjan(int s)
    {
        dfn[s] = low[s] = ++Time;
        sta.push(s);
        ins[s] = 1;
        for(int i=0;i<gra[s].size();i++)
        {
            int k = gra[s][i];
            if(dfn[k] == 0){
                Tarjan(k);
                low[s] = min(low[s] ,low[k]);
            }
            if(dfn[k] != 0 && ins[k] == 1){
                low[s] = min(low[s] ,dfn[k]);//low[s] = min(low[s] ,low[k]);好像也是对的
            }
        }
        if(dfn[s] == low[s])
        {
            num++;
            while(!sta.empty())
            {
                int temp = sta.top();
                sta.pop();
                ins[temp] = 0;
                if(temp == s) break;
            }
        }
    }
     
    int main()
    {
        int n,m;
        while(scanf("%d%d",&n,&m)&&(n + m))
        {
            memset(dfn,0,sizeof(dfn));
            memset(ins,0,sizeof(ins));
            memset(low,0,sizeof(low));
            while(!sta.empty()) sta.pop();
            for(int i=1;i<=n;i++) gra[i].clear();
            int a,b;
            while(m--)
            {
                scanf("%d%d",&a,&b);
                gra[a].push_back(b);
            }
            num = Time = 0;
            for(int i=1;i<=n;i++)
            {
                if(dfn[i]==0) Tarjan(i);
            }
            if(num > 1) printf("No ");
            else printf("Yes ");
        }
    }

  • 相关阅读:
    判断一个图是否有环 无向图 有向图
    经典算法解析
    图的深度优先遍历DFS(邻接矩阵表示法)
    Prim算法求最小生成树MST以及和kruskal算法的对比
    oracle连接中出现错误ORA12541,ORA12514,ORA01017的解决方法
    visual studio 自动整理代码
    解决Google code和Google group无法登录的问题
    Dijkstra算法求单源最短路径(二)(BFS的改版)
    快速排序算法QuickSort
    推荐资料
  • 原文地址:https://www.cnblogs.com/liwenchi/p/7259327.html
Copyright © 2011-2022 走看看