[HAOI 2006]受欢迎的牛

Posted NaVi_Awson

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[HAOI 2006]受欢迎的牛相关的知识,希望对你有一定的参考价值。

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]受欢迎的牛的主要内容,如果未能解决你的问题,请参考以下文章

[HAOI2006]受欢迎的牛

bzoj1051 [HAOI2006]受欢迎的牛

bzoj1051HAOI2006受欢迎的牛

[HAOI2006]受欢迎的牛

bzoj1051: [HAOI2006]受欢迎的牛(强联通)

bzoj1051 [HAOI2006]受欢迎的牛