We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
There was an error while loading. Please reload this page.
1 parent 3452bba commit 3297a4dCopy full SHA for 3297a4d
3 files changed
library/trees/centroid_decomp.hpp
@@ -1,12 +1,12 @@
1
#pragma once
2
//! @code
3
//! vector<basic_string<int>> g(n);
4
-//! centroid(g, [&](int cent, int par_cent) {});
+//! vi par = cd(g, [&](int cent) {});
5
//! @endcode
6
//! @time O(n log n)
7
//! @space O(n)
8
-void centroid(auto& g, auto f) {
9
- vi siz(sz(g));
+vi cd(auto& g, auto f) {
+ vi p(sz(g), -1), siz(p);
10
auto ctd = [&](auto ctd, int u, int p, int n) -> int {
11
siz[u] = 1;
12
for (int v : g[u])
@@ -16,10 +16,10 @@ void centroid(auto& g, auto f) {
16
}
17
return 2 * siz[u] >= n ? siz[p] = n - siz[u], u : -1;
18
};
19
- auto dfs = [&](auto dfs, int u, int p, int n) -> void {
20
- f(u = ctd(ctd, u, u, n), p);
21
- for (int v : g[u])
22
- erase(g[v], u), dfs(dfs, v, u, siz[v]);
+ auto dfs = [&](auto dfs, int u, int n) -> int {
+ f(u = ctd(ctd, u, u, n));
+ for (int v : g[u]) erase(g[v], u), p[dfs(dfs, v, siz[v])] = u;
+ return u;
23
24
- dfs(dfs, 0, -1, sz(g));
+ return dfs(dfs, 0, sz(g)), p;
25
tests/library_checker_aizu_tests/cd_asserts.hpp
@@ -3,25 +3,24 @@
void cd_asserts(vector<vector<int>> adj) {
vector<int> decomp_size(sz(adj), -1);
vector<int> naive_par_decomp(sz(adj), -1);
- centroid(adj, [&](int cent, int par_cent) -> void {
- assert(naive_par_decomp[cent] == par_cent);
+ vi par = cd(adj, [&](int cent) -> void {
assert(decomp_size[cent] == -1);
auto dfs = [&](auto&& self, int u, int p) -> int {
- naive_par_decomp[u] = cent;
+ if (p != -1) naive_par_decomp[u] = cent;
int sub_size = 1;
for (int v : adj[u])
13
if (v != p) sub_size += self(self, v, u);
14
return sub_size;
15
decomp_size[cent] = dfs(dfs, cent, -1);
- if (par_cent != -1)
- assert(1 <= decomp_size[cent] &&
- 2 * decomp_size[cent] <= decomp_size[par_cent]);
for (int u : adj[cent]) {
int sz_subtree = dfs(dfs, u, cent);
- assert(1 <= sz_subtree &&
- 2 * sz_subtree <= decomp_size[cent]);
+ assert(1 <= sz_subtree && 2 * sz_subtree <= decomp_size[cent]);
});
26
- rep(i, 0, sz(adj)) assert(decomp_size[i] >= 1);
+ assert(par == naive_par_decomp);
+ rep(i, 0, sz(adj)) {
+ assert(decomp_size[i] >= 1);
+ if (par[i] != -1) assert(2 * decomp_size[i] <= decomp_size[par[i]]);
+ }
27
tests/library_checker_aizu_tests/trees/cd_count_paths_per_length.test.cpp
@@ -11,7 +11,7 @@
//! which are each O(n)
vector<ll> count_paths_per_length(vector<vi> adj) {
vector<ll> num_paths(sz(adj));
- centroid(adj, [&](int cent, int) {
+ cd(adj, [&](int cent) {
vector<vector<double>> child_depths;
for (int v : adj[cent]) {
child_depths.emplace_back(1, 0.0);
@@ -29,15 +29,13 @@ vector<ll> count_paths_per_length(vector<vi> adj) {
29
swap(q, new_q);
30
31
32
- sort(all(child_depths),
33
- [&](auto& x, auto& y) { return sz(x) < sz(y); });
+ sort(all(child_depths), [&](auto& x, auto& y) { return sz(x) < sz(y); });
34
vector total_depth(1, 1.0);
35
for (const auto& cnt_depth : child_depths) {
36
auto prod = conv(total_depth, cnt_depth);
37
rep(i, 1, sz(prod)) num_paths[i] += llround(prod[i]);
38
total_depth.resize(sz(cnt_depth));
39
- rep(i, 1, sz(cnt_depth)) total_depth[i] +=
40
- cnt_depth[i];
+ rep(i, 1, sz(cnt_depth)) total_depth[i] += cnt_depth[i];
41
42
43
return num_paths;
0 commit comments