强连通图缩点——cf999E
问题转换成缩点求度数为0的点的个数,s点所在联通块作额外处理
缩点写的很烂调了一早上。。
#include<bits/stdc++.h> #include<vector> using namespace std; #define maxn 5005 vector<int>G[maxn]; int n,m,s; int low[maxn],dfn[maxn],ind,stk[maxn],top,ins[maxn],c[maxn],cnt; void Tarjan(int x){ dfn[x]=low[x]=++ind; stk[++top]=x;ins[x]=1; for(int i=0;i<G[x].size();i++){ int y=G[x][i]; if(!dfn[y]){ Tarjan(y); low[x]=min(low[x],low[y]); } else if(ins[y]) low[x]=min(low[x],low[y]); } if(low[x]==dfn[x]){ cnt++;int y; do{ y=stk[top--]; ins[y]=0; c[y]=cnt; }while(x!=y); } } int main(){ cin>>n>>m>>s; for(int i=1;i<=m;i++){ int u,v; cin>>u>>v; G[u].push_back(v); } for(int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i); //缩点重建 int in[maxn]={}; in[c[s]]++; for(int u=1;u<=n;u++){ for(int i=0;i<G[u].size();i++) if(c[u]!=c[G[u][i]]) in[c[G[u][i]]]++; } int ans=0; for(int i=1;i<=cnt;i++) if(in[i]==0)ans++; cout<<ans<<'\n'; }