#include<vector>
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define Min(a,b) a>b?b:a
#define M 10010 //题目中可能的最大点数
vector <int> Edge[M]; //图用邻接表表示
int STACK[M],top=0; //Tarjan 算法中的栈
bool InStack[M]; //检查是否在栈中
int DFN[M]; //深度优先搜索访问次序
int Low[M]; //能追溯到的最早的次序
int cnt; //有向图强连通分量个数
int Index=0; //索引号
int belong[M],n; //记录每个点在第几号强连通分量里 //int ComponentDegree[M]; //记录每个强连通分量的度
void Tarjan(int i)
{ int j;
DFN[i]=Low[i]=Index++;
InStack[i]=true;
STACK[++top]=i;
for (int e=0;e<Edge[i].size();e++)
{ j=Edge[i][e];
if (DFN[j]==-1)
{ Tarjan(j);
Low[i]=Min(Low[i],Low[j]); }
else if (InStack[j])
Low[i]=Min(Low[i],DFN[j]);
}
if (DFN[i]==Low[i]){ //因为每一个节点的DFN都是唯一的,所以,当DFN[i]=Low[i]时,即又回到原先的点
cnt++;//强连通分量的个数或者说是序号
do{ j=STACK[top--];
InStack[j]=false;
belong[j]=cnt; }while(j!=i);
} }
void solve()
{ cnt=0;
memset(STACK,-1,sizeof(STACK));
memset(InStack,0,sizeof(InStack));
memset(DFN,-1,sizeof(DFN));
memset(Low,-1,sizeof(Low));
for(int i=1;i<=n;i++)
if(DFN[i]==-1) Tarjan(i);
}
int chu[M];
int main()
{ int i,j,m;
while(scanf("%d%d",&n,&m)!=EOF){
for(i=1;i<=n;i++){ Edge[i].clear(); }
for(i=0;i<m;i++)
{ int a,b; scanf("%d%d",&a,&b); Edge[a].push_back(b); }
solve();
memset(chu,0,sizeof(chu));
for(i=1;i<=n;i++)
{ for(j=0;j<Edge[i].size();j++)
{ int v=Edge[i][j];
if(belong[i]==belong[v]) continue;
chu[belong[i]]++;
} }
int flag=0;
for(i=1;i<=cnt;i++)
if(chu[i]==0) flag++;
if(flag!=1)
{ puts("0"); }
else
{ int pos;
for(i=1;i<=cnt;i++)
{ if(chu[i]==0) pos=i; }
int ans=0;
for(i=1;i<=n;i++)
{ if(belong[i]==pos) ans++; }
printf("%d\n",ans);
} }
return 0; }
浙公网安备 33010602011771号