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代码
原文地址:https://www.cnblogs.com/xcw0754/p/4627310.html