题意:判断一个有向图是不是一个强连通分量,是的话输出“Yes”,不是的话输出“No”。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1269
——>>直接Tarjan。
#include <cstdio>
#include <vector>
#include <cstring>
#include <stack>
#include <algorithm>using namespace std;const int maxn = 10000 + 10;
vector<int> G[maxn];
int scc_cnt, dfs_clock, pre[maxn], lowlink[maxn], sccno[maxn];
stack<int> st;void dfs(int u)
{lowlink[u] = pre[u] = ++dfs_clock;st.push(u);int d = G[u].size();for(int i = 0; i < d; 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 = st.top();st.pop();sccno[x] = scc_cnt;if(x == u) break;}}
}
void find_scc(int n)
{dfs_clock = scc_cnt = 0;memset(pre, 0, sizeof(pre));memset(sccno, 0, sizeof(sccno));for(int i = 1; i <= n; i++)if(!pre[i]) dfs(i);
}
int main()
{int N, M, i, A, B;while(~scanf("%d%d", &N, &M)){if(!N && !M) return 0;for(i = 1; i <= N; i++) G[i].clear();for(i = 0; i < M; i++){scanf("%d%d", &A, &B);G[A].push_back(B);}find_scc(N);if(scc_cnt == 1) printf("Yes\n");else printf("No\n");}return 0;
}