题意:给出n个节点和m条边,判断这张图是不是强连通图。
第一次学习Tarjan算法,以下是Tarjan算法模板。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define N 11000
#define M 110000
using namespace std;
struct node
{
int next,v;
}e[M];
int head[N],dfn[N],low[N],v[N],q[N],cnt,scnt,top,n,m,blong[N];
void init()
{
memset(head,-1,sizeof(head));
memset(dfn,0,sizeof(dfn));
cnt=top=scnt=0;
}
void add_edge(int u,int v)
{
e[cnt].v=v;
e[cnt].next=head[u];
head[u]=cnt++;
}
void tarjan(int u)
{
int t;
dfn[u]=low[u]=cnt++;
v[u]=1;
q[top++]=u;
for(int i=head[u];i!=-1;i=e[i].next)
{
int c=e[i].v;
if(!dfn[c])
{
tarjan(c);
low[u]=min(low[u],low[c]);
}
else if(v[c])
low[u]=min(low[u],dfn[c]);
}
if(dfn[u]==low[u])
{
scnt++;
do
{
t=q[--top];
v[t]=0;
blong[t]=scnt;
}while(t!=u);
}
}
void solve()
{
for(int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i);
}
int main()
{
while(~scanf("%d%d",&n,&m)&&(n||m))
{
init();
for(int i=0;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add_edge(u,v);
}
solve();
cout<<(scnt==1?"Yes":"No")<<endl;
}
}