tarjan算法
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
#include <stack>
#define inf 0x3f3f3f3f
#define ll long long
#define exp 1e-8
using namespace std;
const int N=1e4+5;
int n,m,dfn[N],low[N],time;//dfn为最先访问的时间点
//low为本节点通过他的儿子更新到的最小时间点
stack<int> s;
int vis[N],res;
vector<int> a[N];
void dfs(int x)
{
dfn[x]=low[x]=++time;
s.push(x);
vis[x]=1;
for(int i=0;i<a[x].size();i++)
{
int y=a[x][i];
if(dfn[y]==0)//未访问过
{
dfs(y);//相当于后序遍历
low[x]=min(low[x],low[y]);
}
else if(vis[y]==1)//访问过,但y在stack中
low[x]=min(low[x],low[y]);
}
if(dfn[x]==low[x])//强连通分量起点
{
res++;
while(s.top()!=x)
{
vis[s.top()]=0;
s.pop();
}
vis[x]=0;
s.pop();
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int x,y;
while(cin >> n >> m)
{
if(n==0&&m==0)
break;
for(int i=1;i<=n;i++)
a[i].clear();
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
while(m--)
{
cin >> x >> y;
a[x].push_back(y);
}
time=0;
res=0;
for(int i=1;i<=n;i++)
{
if(dfn[i]==0)
dfs(i);
}
if(res==1)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}