[洛谷P1726]上白泽慧音

题目传送门

这道题跟求强连通分量有关。这里用的是$Tarjan$。

 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 = 5000 + 5, maxm = 50000 + 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 sccno[maxn], cnt[maxn], low[maxn], pre[maxn], sc, dfs_clock;
31     stack<int> s;
32     void init(int n) {
33         this->n = n;
34         sc = 0;
35         m = 0;
36         memset(G, 0, sizeof(G));
37     }
38     void Add(int u, int v) {
39         edges[++m] = (Edge){u, v, G[u]};
40         G[u] = m;
41     }
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             int v = edges[i].v;
47             if (!pre[v]) {
48                 dfs(v);
49                 minn(low[u], low[v]);
50             } else
51             if (!sccno[v]) minn(low[u], pre[v]);
52         }
53         if (pre[u] == low[u]) {
54             sc++; int x = 0;
55             while (x != u) {
56                 x = s.top(); s.pop();
57                 sccno[x] = sc;
58                 cnt[sc]++;
59             }
60         }
61     }
62 } G;
63 
64 int n, m;
65 
66 int main() {
67     n = read(), m = read();
68     rep(i, 1, m) {
69         int u = read(), v = read(), opt = read();
70         G.Add(u, v);
71         if (opt == 2) G.Add(v, u);
72     }
73 
74     rep(i, 1, n)
75         if (!G.sccno[i])
76             G.dfs(i);
77 
78     int ans = 0;
79 
80     rep(i, 1, n) if (G.cnt[G.sccno[i]] > G.cnt[G.sccno[ans]]) ans = i;
81     printf("%d\n", G.cnt[G.sccno[ans]]);
82     rep(i, 1, n) if (G.cnt[G.sccno[i]] == G.cnt[G.sccno[ans]]) printf("%d ", i);
83 
84     return 0;
85 }

猜你喜欢

转载自www.cnblogs.com/ac-evil/p/10328022.html