/*
*State: HDU1269    46MS    1428K    1364 B
*题目大意:
*        给一个n个点,m条边的有向图,判断该图是否为强连通图
*解题思路:
*        用tarjan,但是要注意该图可能有连通分量。
*/
View Code
 1 #include <iostream>
 2 #include <vector>
 3 #include <stdio.h>
 4 #include <stack>
 5 using namespace std;
 6 
 7 const int MAX = 10005;
 8 vector<int> vec[MAX];
 9 stack<int> S;
10 int dfn[MAX], low[MAX], step, in[MAX];
11 int Flag;
12 
13 void addEdge(int u, int v)
14 {
15     vec[u].push_back(v);
16 }
17 
18 void tarjan(int n)
19 {
20     dfn[n] = low[n] = ++step;
21     S.push(n);
22     in[n]++;
23     for(unsigned i = 0; i < vec[n].size(); i++)
24     {
25         int son = vec[n][i];
26         if(dfn[son] == -1)
27         {
28             tarjan(son);
29             low[n] = min(low[n], low[son]);
30         }
31         else if(in[son] != 0)
32             low[n] = min(low[n], dfn[son]);
33     }
34     if(dfn[n] == low[n])
35     {
36         Flag++;
37         int tmp;
38         do
39         {
40             tmp = S.top();
41             in[tmp]--;
42             S.pop();
43         }while(tmp != n && !S.empty());
44     }
45 }
46 
47 void init()
48 {
49     Flag = 0;
50     step = 0;
51     while(!S.empty())
52         S.pop();
53     for(int i = 0; i < MAX; i++)
54     {
55         dfn[i] = low[i] = -1;
56         vec[i].clear();
57         in[i] = 0;
58     }
59 }
60 
61 int main(void)
62 {
63 #ifndef ONLINE_JUDGE
64     freopen("in.txt", "r", stdin);
65 #endif
66     
67     int n, m;
68     while(scanf("%d %d", &n, &m), n || m)
69     {
70         init();
71         for(int i = 0; i < m; i++)
72         {
73             int u, v;
74             scanf("%d %d", &u, &v);
75             addEdge(u, v);
76         }
77         for(int i = 1; i <= n; i++)
78         {
79             if(dfn[i] == -1)
80                 tarjan(i);
81         }
82         if(Flag == 1)
83             printf("Yes\n");
84         else
85             printf("No\n");
86     }
87     return 0;
88 }
posted on 2012-08-16 01:14  cchun  阅读(193)  评论(0编辑  收藏  举报