题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1269
题目大意:判断是否为强连通图
题目思路:Tarjan 算法模板题,只需判断强连通分量个数是否为1
#include<iostream>
#include<cstdio>
#include<cstring>
#define min(x,y) x>y?y:x
#define max(x,y) x>y?x:y
#define maxn 10000
int n,m,edgenum;
struct edge
{
int v,next;
}e[100000];
int head[maxn];
int vis[maxn];
int componentnum;
int stack[maxn],stacksize;
int dfn[maxn],low[maxn];
add(int u,int v)
{
e[edgenum].v=v;
e[edgenum].next=head[u];//同一个顶点的最后输入的一条边
head[u]=edgenum++;
}
void dfs(int u,int num)
{
vis[u]=1;
dfn[u]=low[u]=num;
stack[++stacksize]=u;
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].v;//i是表示边的数量
if(vis[v]==0)
dfs(v,num+1);
if(vis[v]==1)
low[u]=min(low[u],low[v]);
}
if(low[u]==dfn[u])
{
componentnum++;
int k;
do
{
k=stack[stacksize--];
vis[k]=2;//
}while(k!=u);
}
}
void tarjan()
{
memset(vis,0,sizeof(vis));
stacksize=0;
componentnum=0;
for(int u=1;u<=n;u++)
{
if(vis[u]==0)
dfs(u,1);
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0) break;
edgenum=0;
memset(head,-1,sizeof(head));
for(int i=1;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
}
tarjan();
if(componentnum==1)
printf("Yes\n");
else printf("No\n");
}
return 0;
}