Tarjan縮點【洛谷P2341】
阿新 • • 發佈:2018-11-21
傳送門:https://www.luogu.org/problemnew/show/P2341
這題很簡單,不知道為什麼是提高組的題...
主要思路就是先tarjan縮點,然後在DAG上找出度為0的點,如果只有一個出度為0的點,那麼這個點就是的大小就是受歡迎的牛的數目。如果有兩個及以上個點的出度為0,那麼不存在明星牛。
下面是程式碼:
#include <bits/stdc++.h> using namespace std; const int maxn = 1e4+7; vector<int> G[maxn]; int low[maxn],dfn[maxn]; int ins[maxn]; int color[maxn],sum[maxn]; int de[maxn]; stack<int> s; int n,m; int cnt = 0; int tot = 0; void tarjan(int x) { low[x] = dfn[x] = ++cnt; s.push(x); ins[x] = 1; for(int i=0;i<G[x].size();i++) { int v = G[x][i]; if(!dfn[v]) { tarjan(v); low[x] = min(low[x],low[v]); } else if(ins[v]) { low[x] = min(low[x],dfn[v]); } } if(low[x]==dfn[x]) { tot++; while(true) { int tmp = s.top(); s.pop(); sum[color[tmp]=tot]++; ins[tmp] = 0; if(tmp==x) break; } } } int main() { cin>>n>>m; int x,y; for(int i=0;i<m;i++) { cin>>x>>y; G[x].push_back(y); } 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 v = G[i][j]; if(color[i]!=color[v]) { de[color[i]]++; } } } int ans = 0; for(int i=1;i<=tot;i++) { if(!de[i]) { if(ans) { ans = 0; break; } ans = sum[i]; } } cout<<ans<<endl; return 0; }