http://blog.sina.com.cn/s/blog_69a101130100k1cm.html#cmt_3184785
#include <iostream>
#include <string.h>
#include <vector>
#include <algorithm>
#include <stack>
#include <stdio.h>
using namespace std;
#define LL long long
const int maxn = 10000+6;
vector<int>G[maxn];
vector<int>len;
int DFN[maxn],low[maxn],instack[maxn];
stack<int> q;
int tm=0;
int n,m;
void add(int u,int v)
{
len.push_back(v);
G[u].push_back((int)len.size()-1);
}
void tarjan(int now)
{
DFN[now]=low[now]=++tm;
q.push(now);
instack[now]=1;
for(int i=0;i<G[now].size();i++)
{
int to=len[G[now][i]];
if(DFN[to]==0)
{
tarjan(to);
if(low[now]>low[to]) low[now]=low[to];
}
else if(instack[to]==1&&low[now]>DFN[to])
low[now]=DFN[to];//这里是一直让我很疑惑的,为什么不low[now]和low[to]比较,而是DFN[to]
}
if(DFN[now]==low[now])
{
int v;
do
{
//遍历这个强连通分量,可以输出或者干嘛干嘛
v=q.top();
instack[v]=0;
q.pop();
}while(now!=v);
}
}
void init()
{
for(int i=0;i<maxn;i++)
{
G[i].clear();
}
while(!q.empty()) q.pop();
len.clear();
memset(DFN,0,sizeof DFN);
memset(low,0,sizeof low);
memset(instack,0,sizeof instack);
}
int main()
{
while(~scanf("%d %d",&n,&m))
{
if(n==m&&n==0) break;
init();
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d %d",&u,&v);
add(u,v);
}
for(int i=1;i<=n;i++)
if(DFN[i]==0)
tarjan(i);
}
}