https://www.luogu.com.cn/problem/P2746
第二问, 就是在 入度为0(或者出度为0)那排的点之间加边
#include <bits/stdc++.h> using namespace std ; const int N=1e4+2; vector<int> g[N]; stack<int> st ; int n,m,dfn[N],pool,low[N]; int sz[N],cl,id[N]; void tar(int x){ dfn[x]=low[x]=++pool; st.push(x); int i,y; for(i=0;i<g[x].size();i++){ y=g[x][i]; if(dfn[y]==0) tar(y),low[x]=min(low[x],low[y]); else if(id[y]==0) low[x]=min(low[x],dfn[y]); } if(low[x]==dfn[x]){ ++cl; do{ y= st.top(); st.pop(); id[y]=cl; sz[cl]++; }while(x!=y) ; } } int main(){ int i,x,y,c; cin>>n>>m; for(i=1;i<=m;i++){ cin>>x>>y; g[x].push_back(y); } for(i=1;i<=n;i++) if(!dfn[i]) tar(i); c=0; for(i=1;i<=cl;i++) if(sz[i]>1) c++; cout<<c; }