|
7 | 7 | //! @space O(n) |
8 | 8 | void centroid(auto& g, auto f) { |
9 | 9 | vi siz(sz(g)); |
10 | | - auto dfs_sz = [&](auto&& dfs_sz, int u, int p) -> void { |
| 10 | + auto cnt = [&](auto&& cnt, int u, int p, int n) -> int { |
11 | 11 | siz[u] = 1; |
12 | 12 | for (int v : g[u]) |
13 | | - if (v != p) dfs_sz(dfs_sz, v, u), siz[u] += siz[v]; |
| 13 | + if (v != p) { |
| 14 | + int c = cnt(cnt, v, u, n); |
| 15 | + if (c != -1) return c; |
| 16 | + siz[u] += siz[v]; |
| 17 | + } |
| 18 | + return 2 * siz[u] >= n ? siz[p] = n - siz[u], u : -1; |
14 | 19 | }; |
15 | | - auto dfs = [&](auto&& dfs, int u, int p) -> void { |
16 | | - dfs_sz(dfs_sz, u, -1); |
17 | | - for (int w = -1, sz_root = siz[u];;) { |
18 | | - auto big_ch = ranges::find_if(g[u], [&](int v) { |
19 | | - return v != w && 2 * siz[v] > sz_root; |
20 | | - }); |
21 | | - if (big_ch == end(g[u])) break; |
22 | | - w = u, u = *big_ch; |
23 | | - } |
24 | | - f(u, p); |
25 | | - for (int v : g[u]) erase(g[v], u), dfs(dfs, v, u); |
| 20 | + auto dfs = [&](auto&& dfs, int u, int p, int n) -> void { |
| 21 | + f(u = cnt(cnt, u, u, n), p); |
| 22 | + for (int v : g[u]) |
| 23 | + erase(g[v], u), dfs(dfs, v, u, siz[v]); |
26 | 24 | }; |
27 | | - dfs(dfs, 0, -1); |
| 25 | + dfs(dfs, 0, -1, sz(g)); |
28 | 26 | } |
0 commit comments