HDU1269 迷宫城堡(有向图的强连通分量(scc))
题目链接。
题意:
判断是否有向图是否强连通。
分析:
模板题。判断一个图是否为强连通,即用Tarjan算法看强连通分量(SCC)是否为1.
#include <iostream> #include <vector> #include <stack> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; const int maxn = 10000+10; const int maxm = 100000+10; vector<int> G[maxn]; stack<int> S; int pre[maxn], lowlink[maxn], scc_cnt, sccno[maxn], dfs_clock; void dfs(int u){ pre[u] = lowlink[u] = ++dfs_clock; S.push(u); for(int i=0; i<G[u].size(); i++){ int v = G[u][i]; if(!pre[v]){ dfs(v); lowlink[u] = min(lowlink[u], lowlink[v]); } else if(!sccno[v]){ lowlink[u] = min(lowlink[u], pre[v]); } } if(lowlink[u] == pre[u]){ scc_cnt++; for(;;){ int x = S.top(); S.pop(); sccno[x] = scc_cnt; if(x == u) break; } } } void find_scc(int n){ scc_cnt = dfs_clock = 0; memset(pre, 0, sizeof(pre)); memset(sccno, 0, sizeof(sccno)); for(int i=0; i<n; i++){ if(!pre[i]) dfs(i); } } int main(){ int n, m, u, v; while(scanf("%d%d", &n, &m) == 2){ if(n == 0 && m == 0) break; for(int i=0; i<n; i++) G[i].clear(); for(int i=0; i<m; i++){ scanf("%d%d", &u, &v); u--; v--; G[u].push_back(v); } find_scc(n); if(scc_cnt == 1) printf("Yes\n"); else printf("No\n"); } return 0; }