#include<stdio.h>//用于求一个图存在多少个强连通分量 #include<string.h> #include<vector> using namespace std; #define maxn 1000000 vector<int >mp[maxn]; int vis[maxn];//标记该点是否被tarjan int dfn[maxn];//时间戳 int low[maxn];//low为该点能追溯到的最根的祖先 int n,m,cnt,sig; void init() { memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++)mp[i].clear(); } void Tarjan(int u) { vis[u]=1;//标记该点已访问 low[u]=dfn[u]=cnt++;//时间戳与low程度初始 for(int i=0;i<mp[u].size();i++) { int v=mp[u][i]; if(vis[v]==0)Tarjan(v); if(vis[v]==1)low[u]=min(low[u],low[v]);//回溯,更新low } if(dfn[u]==low[u])//找到一个强连通分量 { sig++;//强连通分支数 } } void Slove() { cnt=1;sig=0; for(int i=1;i<=n;i++)//对所有未被访问的点tarjan { if(vis[i]==0) { Tarjan(i); } } printf("%d ",sig); } int main() { while(~scanf("%d",&n)) { if(n==0)break; scanf("%d",&m); init(); for(int i=0;i<m;i++) { int x,y; scanf("%d%d",&x,&y); mp[x].push_back(y); } Slove(); } } /* 7 9 1 2 2 3 3 1 2 4 4 7 7 4 4 5 5 6 6 4 8 10 1 2 2 3 3 1 2 4 4 7 7 4 4 5 5 6 6 4 7 8 */ /* 2 3 */