Skip to content

Commit fc81660

Browse files
committed
add back centroid test
1 parent 0816ec2 commit fc81660

4 files changed

Lines changed: 88 additions & 71 deletions

File tree

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,27 @@
11
#pragma once
2+
#include "../../library/trees/centroid_decomp.hpp"
3+
void cd_asserts(vector<vector<int>> adj) {
4+
vector<int> decomp_size(sz(adj), -1);
5+
vector<int> naive_par_decomp(sz(adj), -1);
6+
centroid(adj, [&](int cent, int par_cent) -> void {
7+
assert(naive_par_decomp[cent] == par_cent);
8+
assert(decomp_size[cent] == -1);
9+
auto dfs = [&](auto&& self, int u, int p) -> int {
10+
naive_par_decomp[u] = cent;
11+
int sub_size = 1;
12+
for (int v : adj[u])
13+
if (v != p) sub_size += self(self, v, u);
14+
return sub_size;
15+
};
16+
decomp_size[cent] = dfs(dfs, cent, -1);
17+
if (par_cent != -1)
18+
assert(1 <= decomp_size[cent] &&
19+
2 * decomp_size[cent] <= decomp_size[par_cent]);
20+
for (int u : adj[cent]) {
21+
int sz_subtree = dfs(dfs, u, cent);
22+
assert(1 <= sz_subtree &&
23+
2 * sz_subtree <= decomp_size[cent]);
24+
}
25+
});
26+
rep(i, 0, sz(adj)) assert(decomp_size[i] >= 1);
27+
}

tests/library_checker_aizu_tests/handmade_tests/count_paths.test.cpp

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,7 @@
66
#include "../../../kactl/content/numerical/FastFourierTransform.h"
77
#include "../../../library/trees/edge_cd.hpp"
88
#include "../../../library/trees/centroid_decomp.hpp"
9-
void cd_asserts(vector<vector<int>> adj) {
10-
vector<int> decomp_size(sz(adj), -1);
11-
vector<int> naive_par_decomp(sz(adj), -1);
12-
centroid(adj, [&](int cent, int par_cent) -> void {
13-
assert(naive_par_decomp[cent] == par_cent);
14-
assert(decomp_size[cent] == -1);
15-
auto dfs = [&](auto&& self, int u, int p) -> int {
16-
naive_par_decomp[u] = cent;
17-
int sub_size = 1;
18-
for (int v : adj[u])
19-
if (v != p) sub_size += self(self, v, u);
20-
return sub_size;
21-
};
22-
decomp_size[cent] = dfs(dfs, cent, -1);
23-
if (par_cent != -1)
24-
assert(1 <= decomp_size[cent] &&
25-
2 * decomp_size[cent] <= decomp_size[par_cent]);
26-
for (int u : adj[cent]) {
27-
int sz_subtree = dfs(dfs, u, cent);
28-
assert(1 <= sz_subtree &&
29-
2 * sz_subtree <= decomp_size[cent]);
30-
}
31-
});
32-
rep(i, 0, sz(adj)) assert(decomp_size[i] >= 1);
33-
}
9+
#include "../cd_asserts.hpp"
3410
//! @param adj unrooted, connected forest
3511
//! @param k number of edges
3612
//! @returns array `num_paths` where `num_paths[i]` =
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#define PROBLEM \
2+
"https://judge.yosupo.jp/problem/frequency_table_of_tree_distance"
3+
#include "../template.hpp"
4+
#include "../cd_asserts.hpp"
5+
#include "../../../kactl/content/numerical/FastFourierTransform.h"
6+
//! @param adj unrooted, connected forest
7+
//! @returns array `num_paths` where `num_paths[i]` = # of
8+
//! paths in tree with `i` edges. `num_paths[1]` = # edges
9+
//! @time O(n log^2 n)
10+
//! @space this function allocates/returns various vectors
11+
//! which are each O(n)
12+
vector<ll> count_paths_per_length(vector<vi> adj) {
13+
vector<ll> num_paths(sz(adj));
14+
centroid(adj, [&](int cent, int) {
15+
vector<vector<double>> child_depths;
16+
for (int v : adj[cent]) {
17+
child_depths.emplace_back(1, 0.0);
18+
for (queue<pii> q({{v, cent}}); !empty(q);) {
19+
child_depths.back().push_back(sz(q));
20+
queue<pii> new_q;
21+
while (!empty(q)) {
22+
auto [u, p] = q.front();
23+
q.pop();
24+
for (int w : adj[u]) {
25+
if (w == p) continue;
26+
new_q.push({w, u});
27+
}
28+
}
29+
swap(q, new_q);
30+
}
31+
}
32+
sort(all(child_depths),
33+
[&](auto& x, auto& y) { return sz(x) < sz(y); });
34+
vector total_depth(1, 1.0);
35+
for (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];
41+
}
42+
});
43+
return num_paths;
44+
}
45+
int main() {
46+
cin.tie(0)->sync_with_stdio(0);
47+
int n;
48+
cin >> n;
49+
vector<vector<int>> adj(n);
50+
for (int i = 0; i < n - 1; i++) {
51+
int u, v;
52+
cin >> u >> v;
53+
adj[u].push_back(v);
54+
adj[v].push_back(u);
55+
}
56+
cd_asserts(adj);
57+
vector<ll> cnt_len = count_paths_per_length(adj);
58+
for (int i = 1; i < n; i++) cout << cnt_len[i] << " ";
59+
cout << '\n';
60+
return 0;
61+
}

tests/library_checker_aizu_tests/trees/count_paths_per_length.test.cpp

Lines changed: 0 additions & 46 deletions
This file was deleted.

0 commit comments

Comments
 (0)