裸的强连通分量。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+5;
vector<int> e[maxn];
int n,m;
int low[maxn],dfn[maxn],t=0,cnt=0,bel[maxn],num[maxn];
stack<int> st;
void tarjan(int u){
low[u]=dfn[u]=++t;
st.push(u);
for(auto v:e[u]){
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(!bel[v])low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
++cnt;
while(1){
if(st.empty())break;
int v=st.top();
num[cnt]++;
bel[v]=cnt;
if(v==u){
st.pop();
break;
}
st.pop();
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
e[x].push_back(y);
}
for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);//第一次写成了tarjan(1)……
int ans=0;
for(int i=1;i<=cnt;i++){
if(num[i]>1)ans++;
}
cout<<ans;
return 0;
}