1. 程式人生 > >[HAOI 2006]受歡迎的牛

[HAOI 2006]受歡迎的牛

願望 div tput set 一個數 next ret pat 數據

Description

  每一頭牛的願望就是變成一頭最受歡迎的牛。現在有N頭牛,給你M對整數(A,B),表示牛A認為牛B受歡迎。 這種關系是具有傳遞性的,如果A認為B受歡迎,B認為C受歡迎,那麽牛A也認為牛C受歡迎。你的任務是求出有多少頭牛被所有的牛認為是受歡迎的。

Input

  第一行兩個數N,M。 接下來M行,每行兩個數A,B,意思是A認為B是受歡迎的(給出的信息有可能重復,即有可 能出現多個A,B)

Output

  一個數,即有多少頭牛被所有的牛認為是受歡迎的。

Sample Input

3 3
1 2
2 1
2 3

Sample Output

1

HINT

100%的數據N<=10000,M<=50000

題解

好久沒打$tarjan$了,碼在這當模板存著。

 1 //It is made by Awson on 2017.9.24
 2 #include <set>
 3 #include <map>
 4 #include <cmath>
 5 #include <ctime>
 6 #include <queue>
 7 #include <stack>
 8 #include <vector>
 9 #include <string
> 10 #include <cstdio> 11 #include <cstdlib> 12 #include <cstring> 13 #include <iostream> 14 #include <algorithm> 15 #define LL long long 16 #define Min(a, b) ((a) < (b) ? (a) : (b)) 17 #define Max(a, b) ((a) > (b) ? (a) : (b)) 18 using namespace std;
19 const int N = 10000; 20 const int M = 50000; 21 int Read() { 22 char ch = getchar(); 23 int sum = 0; 24 while (ch < 0 || ch > 9) ch = getchar(); 25 while (ch >= 0 && ch <= 9) sum = (sum<<3)+(sum<<1)+ch-48, ch = getchar(); 26 return sum; 27 } 28 29 int n, m, u, v; 30 struct tt { 31 int from, to, next; 32 }edge[M+5]; 33 int path[N+5], top; 34 int dfn[N+5], low[N+5], t; 35 bool vis[N+5]; 36 int S[N+5], topS; 37 int sccno[N+5], sccnum; 38 int in[N+5], tot[N+5]; 39 40 void add(int u, int v) { 41 edge[++top].to = v; 42 edge[top].from = u; 43 edge[top].next = path[u]; 44 path[u] = top; 45 } 46 void tarjan(int r) { 47 dfn[r] = low[r] = ++t; 48 vis[r] = 1; 49 S[topS++] = r; 50 for (int i = path[r]; i; i = edge[i].next) { 51 if (!dfn[edge[i].to]) { 52 tarjan(edge[i].to); 53 low[r] = Min(low[edge[i].to], low[r]); 54 } 55 else if (vis[edge[i].to]) 56 low[r] = Min(low[r], dfn[edge[i].to]); 57 } 58 if (dfn[r] == low[r]) { 59 sccnum++; 60 while (topS > 0 && S[topS] != r) { 61 vis[S[--topS]] = 0; 62 sccno[S[topS]] = sccnum; 63 tot[sccnum]++; 64 } 65 } 66 } 67 void work() { 68 n = Read(), m = Read(); 69 for (int i = 1; i <= m; i++) { 70 u = Read(), v = Read(); 71 add(u, v); 72 } 73 for(int i = 1; i <= n; i++) 74 if(!dfn[i]) tarjan(i); 75 for (int i = 1; i <= m; i++) 76 if (sccno[edge[i].to] != sccno[edge[i].from]) 77 in[sccno[edge[i].from]]++; 78 int ans = 0, cntt = 0; 79 for (int i = 1; i <= sccnum; i++) 80 if (!in[i]) cntt++, ans=i; 81 if (cntt == 1) printf("%d\n", tot[ans]); 82 else printf("0\n"); 83 } 84 int main() { 85 work(); 86 return 0; 87 }

[HAOI 2006]受歡迎的牛