#include<bits/stdc++.h> using namespace std; #define maxn 5050 vector<int>G[maxn]; int low[maxn],dfn[maxn],stk[maxn],in[maxn],out[maxn]; int top,cnt,tme,color[maxn],n,m,k; bool instack[maxn]; void tarjan(int u) { int v; low[u]=dfn[u]=++tme; stk[top++]=u; instack[u]=1; for(int i=0; i<G[u].size(); i++) { v=G[u][i]; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } if(instack[v]) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]) { cnt++; do { v=stk[--top]; instack[v]=0; color[v]=cnt; } while(u!=v); } } void solve() { memset(instack,0,sizeof(instack)); memset(stk,0,sizeof(stk)); memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); int sum1,sum2; sum1=sum2=top=cnt=tme=0; for(int i=1; i<=n; i++) if(!dfn[i]) tarjan(i); for(int i=1; i<=n; i++) for(int j=0; j<G[i].size(); j++) { int nextone=G[i][j]; if(color[i]!=color[nextone]) { out[color[i]]++; in[color[nextone]]++; } } for(int i=1; i<=cnt; i++) { if(in[i]==0&&color[k]!=i) { sum1++; } if(out[i]==0) { sum2++; } } cout<<sum1<<endl; } int main() { int x,y; cin>>n>>m>>k; while(m--) { cin>>x>>y; G[x].push_back(y); } solve(); return 0; }
构成超级点之后求入度为0且没有 Capital的超级点 计数输出即可