zoukankan      html  css  js  c++  java
  • HDU 1269 迷宫城堡 (强连通分量,常规)

    题意:

      判断所给的有向图是否是一个强连通图。

    思路:

      如果连通分量大于1则必定No,如果强连通分量大于1也是No。tarjan算法求强连通分量。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <vector>
     5 #include <unordered_map>
     6 #include <stack>
     7 #include <iostream>
     8 #include <bits/stdc++.h>
     9 #define LL long long
    10 #define pii pair<int,int>
    11 using namespace std;
    12 const int N=10000+5;
    13 const int INF=0x7f7f7f7f;
    14 vector<int> vect[N];
    15 stack<int> stac;
    16 int n, m;
    17 
    18 int lowlink[N], dfn[N], scc_no[N];
    19 int dfn_clock, scc_cnt;
    20 
    21 void DFS(int x)
    22 {
    23     stac.push(x);
    24     lowlink[x]=dfn[x]=++dfn_clock;
    25     for(int i=0; i<vect[x].size(); i++)
    26     {
    27         int t=vect[x][i];
    28         if(!dfn[t])
    29         {
    30             DFS(t);
    31             lowlink[x]=min(lowlink[x],lowlink[t]);
    32         }
    33         else if(!scc_no[t])
    34             lowlink[x]=min(lowlink[x],dfn[t]);
    35     }
    36     if(lowlink[x]==dfn[x])
    37     {
    38         scc_cnt++;
    39         while(true)
    40         {
    41             int t=stac.top();
    42             stac.pop();
    43             scc_no[t]=scc_cnt;
    44             if(x==t)    break;
    45         }
    46     }
    47 
    48 }
    49 
    50 
    51 bool cal()
    52 {
    53     memset(lowlink, 0, sizeof(lowlink));
    54     memset(dfn, 0, sizeof(dfn));
    55     memset(scc_no, 0, sizeof(scc_no));
    56 
    57     scc_cnt=dfn_clock=0;
    58     DFS(1);
    59     if(scc_cnt>1)   return false;   //多个强连通分量
    60     for(int i=1; i<=n; i++)    if(!scc_no[i]) return false; //多个连通分量
    61     return true;
    62 }
    63 
    64 
    65 int main()
    66 {
    67     freopen("input.txt", "r", stdin);
    68     int a, b;
    69     while(scanf("%d%d",&n,&m), n+m)
    70     {
    71         for(int i=1; i<=n; i++) vect[i].clear();
    72         for(int i=0; i<m; i++)
    73         {
    74             scanf("%d%d",&a,&b);
    75             vect[a].push_back(b);
    76         }
    77         if(cal())   puts("Yes");
    78         else    puts("No");
    79     }
    80     return 0;
    81 }
    AC代码
  • 相关阅读:
    二叉树计数2(卡特兰数+高精乘低精+高精除低精)
    奶牛的身高(差分约束)
    海底高铁(差分)
    假期(动态规划+单调队列)
    RY哥查字典(字符串双模hash初步)
    元素查找(hash初步)
    【模板】单源最短路径 堆优化的dijkstra
    【模板】单源最短路径spfa
    【并查集】noi2001食物链
    【带权并查集】银河英雄传说
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4627310.html
Copyright © 2011-2022 走看看