http://www.cppblog.com/sosi/archive/2010/09/26/127797.aspx
tarjan算法
#include<iostream>
#include<vector>
#include<stack>
#define maxn 20005
using namespace std;
int n,m;
int t,point;
struct stu
{
int visit;
int dfn;
int low;
int instack;
int root;
void init()
{
root=-1;
dfn=-1;
visit=0;
low=-1;
instack=0;
}
};
vector<int>mapp[maxn];
stack<int>s;
stu h[maxn];
int head[maxn],nextt[maxn];
void init()
{
for(int i=0;i<maxn;i++) mapp[i].clear(),head[i]=0,nextt[i]=0,h[i].init();
while(s.size()) s.pop();
t=1;
point=1;
}
void input()
{
for(int i=0;i<m;i++)
{
int x,y;
cin>>x>>y;
mapp[x].push_back(y);
}
}
void tarjan(int x)
{
s.push(x);
h[x].visit=1;
h[x].dfn=t++;
h[x].instack=1;
h[x].low=h[x].dfn;
for(int i=0;i<mapp[x].size();i++)
{
if(!h[mapp[x][i]].visit)
{
tarjan(mapp[x][i]);
h[x].low=min(h[x].low,h[mapp[x][i]].low);
}
else if(h[mapp[x][i]].instack) h[x].low=min(h[x].low,h[mapp[x][i]].dfn);
}
if(h[x].dfn==h[x].low)
{
int w;
do
{
w=s.top();
h[w].root=point;
h[w].instack=0;
s.pop();
}while(w!=x);
point++;
}
}
int main()
{
while(cin>>n>>m)
{
init();
input();
for(int i=1;i<=n;i++)
{
if(!h[i].visit) tarjan(i);
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<mapp[i].size();j++)
{
if(h[mapp[i][j]].root!=h[i].root) nextt[h[i].root]++,head[h[mapp[i][j]].root]++;
}
}
int in=0,out=0;
for(int i=1;i<point;i++)
{
if(!head[i]) in++;
if(!nextt[i]) out++;
}
if(point==2) cout<<"0"<<endl;
else cout<<max(in,out)<<endl;
}
return 0;
}