PKU 2553 The Bottom of a Graph

http://poj.org/problem?id=2553
有向グラフG(V,E)が与えられる。
ここであるノードvからwへの経路があることを(v→w)と表す。
∀w∈V:(v→w)⇒(w→v) となるようなノードvを全て出力しろというようなもんだい。

以前やった時はTLEであきらめたので今回は多少高速化してみたら何とか通りました。
PKUの調子がわるいせいでいまだにWaitingのやつが残っていてシュール。
何とか通ったものの、自分のコードがあまりに遅いので他の人の実装を調べてみようかと思います。

bool con[5000][5000];
int G[5000][5000];
int Gs[5000];
int ans[5000];
int anss;
bool vis[5000];
int v,e;


void dfs(int u){
  vis[u]=true;
  rep(j,v){
    if(con[u][j])vis[j]=true;
  }
  rep(i,Gs[u]){
    if(vis[G[u][i]])continue;
    dfs(G[u][i]);
  }
}

main(){
  while(scanf("%d",&v),v){
    cin>>e;
    memset(con,0,sizeof(con));
    memset(Gs,0,sizeof(Gs));
    anss=0;
    rep(i,e){
      int a,b;
      scanf("%d%d",&a,&b);
      --a,--b;
      G[a][Gs[a]++]=b;
    }
    rep(i,v){
      memset(vis,0,sizeof(vis));
      dfs(i);
      rep(j,v)
        if(vis[j])con[i][j]=true;
    }

    rep(i,v){
      bool ok=true;
      rep(j,v){
        if(con[i][j]){
          if(con[j][i])continue;
          ok=false;
          break;
        }
      }
      if(ok)ans[anss++]=i+1;
    }
    rep(i,anss){
      if(i)putchar(' ');
      printf("%d",ans[i]);
    }
    putchar('\n');
  }
}