JDOJ-1076: 受歡迎的牛
阿新 • • 發佈:2018-04-22
c++ const return HP tps for sum ID break
Submit: 386 Solved: 131
[Submit][Status][Web Board]
1076: 受歡迎的牛
Time Limit: 1 Sec Memory Limit: 13 MBSubmit: 386 Solved: 131
[Submit][Status][Web Board]
Description
每頭牛都有一個夢想:成為一個群體中最受歡迎的名牛!在一個有N(1<=N<=10,000)頭牛的牛群中,給你M(1<=M<=50,000)個二元組(A,B),表示A認為B是受歡迎的。既然受歡迎是可傳遞的,那麽如果A認為B受歡迎,B又認為C受歡迎,則A也會認為C是受歡迎的,哪怕這不是十分明確的規定。 你的任務是計算被所有其它的牛都喜歡的牛的個數。
Input
第一行,兩個數,N和M。第2~M+1行,每行兩個數,A和B,表示A認為B是受歡迎的。
Output
一個數,被其他所有奶牛認為受歡迎的奶牛頭數。
Sample Input
3 3 1 2 2 1 2 3Sample Output
1HINT
【樣例說明】 3號奶牛是唯一被所有其他奶牛認為有名的。
總結:tarjan縮點,如果出度為0的點為個數0,ans = n,如果出度為0的點個數為1,ans = sum[這個點],如果個數大於1,ans = 0。#include<bits/stdc++.h> usingnamespace 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; }
JDOJ-1076: 受歡迎的牛