强连通分量的模板题,第一次写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;
}