[洛谷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 }