poj2186
//1824K 250MS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#include<stack>
using namespace std;
stack<int>S;
int n,m;
int num[10005];
int ranse;
struct node
{
node *next;
int id;
}head[10005];//数组下标代表id,每条链表代表该点能到达的所有点
int res;
int low[10005];
int dfn[10005];
int color[10005];
bool visit[10005];
bool instack[10005];
int chudu[10005];
int index;
void init()
{
memset(num,0,sizeof(num));
int i;
for(i=1;i<=n;i++)
{
head[i].id=i;
head[i].next=NULL;
visit[i]=false;
instack[i]=false;
chudu[i]=0;
}
while(!S.empty())
{
S.pop();
}
}
void dfs(int u)//节点u
{
visit[u]=true;
dfn[u]=low[u]=++index;
S.push(u);
instack[u]=true;;
node *p;
p=head[u].next;
while(p!=NULL)
{
if(visit[p->id]==false)
{
dfs(p->id);
low[u]=low[u]<low[p->id]?low[u]:low[p->id];
}
else if(instack[p->id])
{
low[u]=low[u]<dfn[p->id]?low[u]:dfn[p->id];
}
p=p->next;
}
int v;
if(dfn[u]==low[u])
{
ranse++;
while(1)
{
v=S.top();S.pop();
color[v]=ranse;
instack[v]=false;
num[ranse]++;
if(v==u)
{
break;
}
}
}
}
bool flag;
int colorchudu[10005];
void calchudu()
{
memset(colorchudu,0,sizeof(colorchudu));
int i;
int ourcolor;
node *p;
int counter;
for(i=1;i<=n;i++)//对每个节点进行标记,每搜到一个节点,记录他的出度,加到整个颜色(整个强连通分量上)的出度上
{
counter=0;
ourcolor=color[head[i].id];
p=head[i].next;
while(p!=NULL)
{
if(color[p->id]!=color[i])
{
counter++;
}
p=p->next;
}
//counter是该节点的出度,现在加到颜色的出度上
colorchudu[ourcolor]+=counter;
}
}
int main()
{
int a,b;
while(scanf("%d %d",&n,&m)!=EOF)
{
flag=false;
res=-1;
init();//初始化变量
int i;
for(i=0;i<m;i++)
{
scanf("%d %d",&a,&b);
node *temp;
temp=head[a].next;
head[a].next=new node;
head[a].next->id=b;
head[a].next->next=temp;
}
index=0;
ranse=0;
for(i=1;i<=n;i++)
{
if(!visit[i])
{
dfs(i);
}
}
calchudu();
int yy=0;
for(i=1;i<=ranse;i++)
{
if(colorchudu[i]==0)
{
res=i;
yy++;
}
}
if(yy==1)
{
if(res==-1)
{
printf("0\n");
continue;
}
if(res!=-1)
{
printf("%d\n",num[res]);
continue;
}
}
else
{
printf("0\n");
continue;
}
}
return 0;
}