先縮點,而後統計有幾個入度爲零的點。ios
然而有重邊和自環。c++
自環須要判斷一下,然而重邊也許不須要判斷?spa
// luogu-judger-enable-o2 #include<bits/stdc++.h> using namespace std; int from[500010],to[500010],nex[500010],head[100010]; int dfn[100010],low[100010],scc[100010],enter[100010]; int sccnum,dfsnum,instack[100010]; stack <int> s; void tarjan(int u) { dfn[u]=low[u]=++dfsnum; instack[u]=1; s.push(u); for(int i=head[u];i;i=nex[i]) { if(!dfn[to[i]]) { tarjan(to[i]); low[u]=min(low[u],low[to[i]]); } else if(instack[to[i]]) low[u]=min(low[u],dfn[to[i]]); } if(dfn[u]==low[u]) { int v; ++sccnum; do { v=s.top(); s.pop(); instack[v]=0; scc[v]=sccnum; }while(u!=v); } return ; } int main() { ios::sync_with_stdio(false); int n,m,x,y,ans=0; cin>>n>>m; for(int i=1;i<=m;i++) { cin>>x>>y; from[i]=x; to[i]=y; nex[i]=head[x]; head[x]=i; } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=m;i++) if(scc[from[i]]!=scc[to[i]]) ++enter[scc[to[i]]]; for(int i=1;i<=sccnum;i++) if(enter[i]==0) ++ans; cout<<ans; return 0; }