Description
每头奶牛都梦想成为牛棚里的明星。被所有奶牛喜欢的奶牛就是一头明星奶牛。所有奶牛都是自恋狂,每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的——如果A喜欢B,B喜欢C,那么A也喜欢C。牛栏里共有N 头奶牛,给定一些奶牛之间的爱慕关系,请你算出有多少头奶牛可以当明星。
Solution
每个奶牛是一个点,将爱慕关系看成边,建图。
考虑如果途中出现环,那么环上的奶牛都可能是大明星,所以可以把一个强连通分量放在一起考虑。
如果只有一个出度为0的强连通分量,那么里面全是明星,如果有两个或两个以上,牛棚里没有明星。
Code
#include<bits/stdc++.h> using namespace std; const int N = 10010,M = 50010; struct Edge{ int u,v,next; }e[M * 2]; int head[N],tot; void add(int u,int v){ e[++tot].next = head[u]; e[tot].v = v; e[tot].u = u; head[u] = tot; } int low[N],dfn[N],s[N],ins[N],c[N],num,cnt,top; vector<int> scc[N]; void tarjan(int u){ low[u] = dfn[u] = ++num; s[++top] = u, ins[u] = 1; for(int i = head[u]; i; i = e[i].next){ int v = e[i].v; if(!dfn[v]){ tarjan(v); low[u] = min(low[u],low[v]); } else if(ins[v]){ low[u] = min(low[u],dfn[v]); } } if(dfn[u] == low[u]){ ++cnt; int v; do{ v = s[top--]; ins[v] = 0; scc[cnt].push_back(v); c[v] = cnt; }while(u != v); } } int n,m,deg[N]; int main(){ cin >> n >> m; for(int i = 1; i <= m; i++){ int a,b; cin >> a >> b; add(a,b); } for(int i = 1; i <= n; i++) if(!dfn[i]) tarjan(i); // for(int i = 1; i <= n; i++)cout << c[i] << endl; for(int i = 1; i <= m; i++){ int u = e[i].u,v = e[i].v; if(c[u] != c[v]) deg[c[u]]++; } int ans = 0; for(int i = 1; i <= cnt; i++){ if(deg[i] == 0){ if(ans){ ans = 0; break; } ans = scc[i].size(); } } cout << ans << endl; return 0; }
来源:https://www.cnblogs.com/FoxC/p/12219450.html