/* *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 }