有向图的强连通图分量,Tarjan算法,模板题。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<stack>
using namespace std;
const int Maxn = 10002;
const int MAX = 100002;
vector <int> G[MAX];
int pre[MAX], lowlink[MAX], sccno[MAX], dfs_clock, scc_cnt;
stack <int> S;
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)
{
dfs_clock = scc_cnt = 0;
memset(sccno, 0, sizeof(sccno));
memset(pre, 0, sizeof(pre));
for(int i=1; i<=n; i++)
if(!pre[i])
dfs(i);
}
int main()
{
#ifdef test
freopen("sample.txt", "r", stdin);
#endif
int n, m;
while(scanf("%d%d", &n, &m))
{
if(!n && !m)
break;
for(int i=1; i<=n; i++)
G[i].clear();
for(int i=1; i<=m; i++)
{
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
}
find_scc(n);
if(scc_cnt<=1)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}