Skip to content

Commit 5072068

Browse files
committed
adding progress
1 parent 4fe5717 commit 5072068

File tree

2 files changed

+36
-13
lines changed

2 files changed

+36
-13
lines changed

library/trees/edge_cd.hpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919
//! });
2020
//! @endcode
2121
//! handle single-edge-paths separately
22-
//! @time O(n log1.5 n)
22+
//! @time O(n logφ n)
2323
//! @space O(n)
24-
template<class F, class G> struct edge_cd {
24+
template <class F, class G>
25+
struct edge_cd {
2526
vector<G> adj;
2627
F f;
2728
vi sub_sz;
28-
edge_cd(const vector<G>& adj, F f):
29-
adj(adj), f(f), sub_sz(sz(adj)) {
29+
edge_cd(const vector<G>& adj, F f) : adj(adj), f(f), sub_sz(sz(adj)) {
3030
dfs(0, sz(adj));
3131
}
3232
int find_cent(int v, int p, int siz) {
@@ -38,17 +38,16 @@ template<class F, class G> struct edge_cd {
3838
sub_sz[v] += sub_sz[u];
3939
}
4040
if (p == -1) return v;
41-
return 2 * sub_sz[v] >= siz
42-
? sub_sz[p] = siz - sub_sz[v],
43-
v : -1;
41+
return 2 * sub_sz[v] >= siz ? sub_sz[p] = siz - sub_sz[v], v : -1;
4442
}
4543
void dfs(int v, int siz) {
4644
if (siz <= 2) return;
4745
v = find_cent(v, -1, siz);
4846
int sum = 0;
4947
auto it = partition(all(adj[v]), [&](int u) {
50-
bool ret = 2 * sum + sub_sz[u] < siz - 1 &&
51-
3 * (sum + sub_sz[u]) <= 2 * (siz - 1);
48+
ll b = sum + sub_sz[u];
49+
ll a = siz - 1 - b;
50+
bool ret = (b * b <= a * (a + b));
5251
if (ret) sum += sub_sz[u];
5352
return ret;
5453
});
Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#pragma once
2-
void edge_cd_asserts(const vector<vi>& adj, int cent,
3-
int split) {
2+
void edge_cd_asserts(const vector<vi>& adj, int cent, int split) {
43
assert(0 < split && split < sz(adj[cent]));
54
auto dfs = [&](auto&& self, int u, int p) -> int {
65
int siz = 1;
@@ -11,12 +10,37 @@ void edge_cd_asserts(const vector<vi>& adj, int cent,
1110
int sz_all = dfs(dfs, cent, -1);
1211
assert(sz_all >= 3);
1312
array<int, 2> cnts = {0, 0};
13+
array<int, 2> max_cnt = {0, 0};
1414
for (int i = 0; i < sz(adj[cent]); i++) {
1515
int sz_subtree = dfs(dfs, adj[cent][i], cent);
1616
assert(2 * sz_subtree <= sz_all);
1717
cnts[i < split] += sz_subtree;
18+
max_cnt[i < split] = max(max_cnt[i < split], sz_subtree);
1819
}
1920
assert(cnts[0] + cnts[1] + 1 == sz_all);
20-
for (int i = 0; i < 2; i++)
21-
assert(0 < cnts[i] && cnts[i] <= 2 * cnts[!i]);
21+
22+
if (sz_all == 4) return;
23+
24+
// a is the number of edges in the smaller edge set
25+
// b is the number of edges in the larger edge set
26+
// so we know 1/2 <= b/(a+b)
27+
// returns true iff b/(a+b) <= 1/phi
28+
auto is_balanced = [&](ll a, ll b) -> bool {
29+
assert(a <= b);
30+
return b * b <= a * (a + b);
31+
};
32+
33+
if (cnts[0] > cnts[1]) {
34+
swap(cnts[0], cnts[1]);
35+
swap(max_cnt[0], max_cnt[1]);
36+
}
37+
38+
if (!is_balanced(cnts[0], cnts[1])) {
39+
int a = max_cnt[1];
40+
int b = cnts[1] - max_cnt[1];
41+
assert(a > 0);
42+
assert(b > 0);
43+
if (a > b) swap(a, b);
44+
assert(is_balanced(a, b));
45+
}
2246
}

0 commit comments

Comments
 (0)