[HAOI2006]受欢迎的牛

题目传送门

这道题实质就是缩点,缩完点后一定是$DAG$,统计每个缩点的大小。如果有且只有一个缩点的出度为$0$,说明其他所有点都会直接或间接到达这个点。

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 #define re register
 6 #define rep(i, a, b) for (re int i = a; i <= b; ++i)
 7 #define repd(i, a, b) for (re int i = a; i >= b; --i)
 8 #define maxx(a, b) a = max(a, b);
 9 #define minn(a, b) a = min(a, b);
10 #define LL long long
11 #define inf (1 << 30)
12 
13 inline int read() {
14     int w = 0, f = 1; char c = getchar();
15     while (!isdigit(c)) f = c == '-' ? -1 : f, c = getchar();
16     while (isdigit(c)) w = (w << 3) + (w << 1) + (c ^ '0'), c = getchar();
17     return w * f;
18 }
19 
20 const int maxn  = 1e4 + 5, maxm = 5e4 + 5;
21 
22 struct Edge {
23     int u, v, pre;
24 };
25 
26 struct Graph {
27     Edge edges[maxm << 1];
28     int n, m;
29     int G[maxn];
30     int dfs_clock, sccno[maxn], scc_cnt, cnt[maxn], pre[maxn], low[maxn];
31     void init(int n) {
32         this->n = n;
33         m = 0;
34         memset(G, 0, sizeof(G));
35         dfs_clock = scc_cnt = 0;
36     }
37     void Add(int u, int v) {
38         edges[++m] = (Edge){u, v, G[u]};
39         G[u] = m;
40     }
41     stack<int> s;
42     void dfs(int u) {
43         pre[u] = low[u] = ++dfs_clock;
44         s.push(u);
45         for (int i = G[u]; i; i = edges[i].pre) {
46             register int v = edges[i].v;
47             if (!pre[v]) {
48                 dfs(v); minn(low[u], low[v]);
49             }
50             else if (!sccno[v]) minn(low[u], pre[v]);
51         }
52         if (pre[u] == low[u]) {
53             int x = 0; scc_cnt++;
54             while (x != u) {
55                 x = s.top(); s.pop();
56                 sccno[x] = scc_cnt;
57                 cnt[scc_cnt]++;
58             }
59         }
60     }
61 } G;
62 
63 int n, m, b[maxn];
64 
65 int main() {
66     n = read(), m = read();
67     G.init(n);
68 
69     rep(i, 1, m) {
70         int u = read(), v = read();
71         G.Add(u, v);
72     }
73     rep(i, 1, n) if (!G.sccno[i]) G.dfs(i);
74 
75     rep(i, 1, G.m) {
76         int u = G.edges[i].u, v = G.edges[i].v;
77         if (G.sccno[u] != G.sccno[v])
78             b[G.sccno[u]] = 1;
79     }
80 
81     int ans = 0;
82     rep(i, 1, G.scc_cnt) 
83         if (!b[i]) {
84             if (ans) { ans = 0; break; }
85             ans = i;
86         }
87 
88     printf("%d", G.cnt[ans]);
89 
90     return 0;
91 }

 

posted @ 2019-01-28 13:04  AC-Evil  阅读(209)  评论(0编辑  收藏  举报