强连通分量的模板题,第一次写tarjan算法,还不是很懂这算法吖~~~
46ms代码
#include<cstdio>
#include<string>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<map>
const int INF=1<26;
using namespace std;
typedef struct edge
{
int t;
edge* next;
}edge;
int index,bcnt,stop;
int DFN[10005],low[10005],stack[10005];
edge *v[10005];
bool instack[10005];
void tarjan(int i)
{
int j;
edge *e;
DFN[i]=low[i]=++index;
instack[i]=true;
stack[++stop]=i;
for(e=v[i];e;e=e->next)
{
j=e->t;
if(!DFN[j])
{
tarjan(j);
if(low[j]<low[i])
low[i]=low[j];
}
else if(instack[j]&&DFN[j]<low[i])
{
low[i]=DFN[j];
}
}
if(low[i]==DFN[i])
{
bcnt++;
do
{
j=stack[stop--];
instack[j]=false;
}
while(j!=i);
}
}
int main()
{
int n,i,m,x,y;
while(scanf("%d %d",&n,&m)&&(n!=0||m!=0))
{
edge *p[10005];
for(i=1;i<=n;i++)
{
v[i]=(edge *)malloc(sizeof(edge));
v[i]->t=i;
v[i]->next=NULL;
p[i]=v[i];
}
for(i=1;i<=m;i++)
{
scanf("%d %d",&x,&y);
p[x]->next=(edge *)malloc(sizeof(edge));
p[x]->next->t=y;
p[x]->next->next=NULL;
p[x]=p[x]->next;
}
stop=bcnt=index=0;
memset(DFN,0,sizeof(DFN));
memset(instack,false,sizeof(instack));
for(i=1;i<=n;i++)
{
if(!DFN[i])
tarjan(i);
if(bcnt>1)
break;
}
if(bcnt==1||n==0)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}