每头牛都有一个梦想:成为一个群体中最受欢迎的名牛!在一个有N(1<=N<=10,000)头牛的牛群中,给你M(1<=M<=50,000)个二元组(A,B),表示A认为B是受欢迎的。既然受欢迎是可传递的,那么如果A认为B受欢迎,B又认为C受欢迎,则A也会认为C是受欢迎的,哪怕这不是十分明确的规定。 你的任务是计算被所有其它的牛都喜欢的牛的个数。
标签:data oid node 个数 计算 mes top oar AC
每头牛都有一个梦想:成为一个群体中最受欢迎的名牛!在一个有N(1<=N<=10,000)头牛的牛群中,给你M(1<=M<=50,000)个二元组(A,B),表示A认为B是受欢迎的。既然受欢迎是可传递的,那么如果A认为B受欢迎,B又认为C受欢迎,则A也会认为C是受欢迎的,哪怕这不是十分明确的规定。 你的任务是计算被所有其它的牛都喜欢的牛的个数。
第一行,两个数,N和M。第2~M+1行,每行两个数,A和B,表示A认为B是受欢迎的。
一个数,被其他所有奶牛认为受欢迎的奶牛头数。
【样例说明】 3号奶牛是唯一被所有其他奶牛认为有名的。
#include<bits/stdc++.h> using namespace std; const int maxn = 100005; int dfn[maxn], low[maxn], head[maxn << 1]; bool vis[maxn]; int n, m, cnt = 1, sum[maxn]; struct Node{ int v, nxt; }G[maxn << 1]; void insert(int u, int v) { G[cnt] = (Node) {v, head[u]}; head[u] = cnt++; } stack<int> s; int tot = 0, color[maxn], tim = 0; void tarjan(int x) { vis[x] = true; s.push(x); dfn[x] = low[x] = ++tim; for (int i = head[x]; i; i = G[i].nxt) { int v = G[i].v; if(!dfn[v]) { tarjan(v); low[x] = min(low[x], low[v]); } else if(vis[v]) low[x] = min(low[x], dfn[v]); } if(dfn[x] == low[x]) { tot++; while(1) { int now = s.top(); vis[now] = false; s.pop(); color[now] = tot; sum[tot]++; if(now == x) break; } } } int chu[maxn]; int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= m; ++i) { int x, y; scanf("%d%d", &x, &y); insert(x, y); } for (int i = 1; i <= n; ++i) if(!dfn[i]) tarjan(i); for (int u = 1; u <= n; ++u) { for (int i = head[u]; i; i = G[i].nxt) { int v = G[i].v; if(color[u] != color[v]) chu[color[u]]++; } } int ans = 0; int fl = 0; for (int i = 1; i <= tot; ++i) if(chu[i] == 0) ans = sum[i], fl++; if(fl > 1) printf("0\n"); else if(fl == 0) printf("%d\n", n); else printf("%d\n", ans); return 0; }
标签:data oid node 个数 计算 mes top oar AC
原文地址:https://www.cnblogs.com/oi-forever/p/8908417.html