P2863 [USACO06JAN]牛的舞會The Cow Promspa
用\(tarjan\)求出強連通份量,而且記錄出強連通份量裏的點的個數,若是個數大於\(1\)就\(ans++\)code
#include<bits/stdc++.h> #include<vector> #include<stack> using namespace std; const int N=50010; int dfn[N],low[N],sum,top,vis[N],col[N]; vector<int>g[N]; stack<int> q; int num2; int ans; int tot[N]; int n,m,dep; void tarjan(int u) { ++dep; dfn[u]=low[u]=dep; q.push(u); vis[u]=1; int len=g[u].size(); for(int i=0; i<len; ++i) { int v=g[u][i]; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else { if(vis[u]) low[u]=min(low[u],low[v]); } } if(dfn[u]==low[u])//找到強聯通份量了 { sum++; num2++; col[u]=sum; vis[u]=0; tot[num2]++; while(q.top()!=u) { int Top=q.top(); q.pop(); col[Top]=sum; tot[num2]++; vis[Top]=0; } q.pop(); } } signed main() { cin>>n>>m; for(int i=1; i<=m; ++i) { int x,y; cin>>x>>y; g[x].push_back(y); } for(int i=1; i<=n; ++i) //if(!col[i]) tarjan(i); if(!dfn[i]) tarjan(i); for(int i=1;i<=num2;++i) if(tot[i]>1) ans++; cout<<ans; return 0; }
if(dfn[u]==low[u])//找到強聯通份量了 { sum++; num2++; col[u]=sum; vis[u]=0; tot[num2]++;//沒有這一句 while(q.top()!=u) { int Top=q.top(); q.pop(); col[Top]=sum; tot[num2]++; vis[Top]=0; } q.pop(); }
少算了割點ci