Skip to content

Commit 1cfa596

Browse files
committed
rerooting: refactoring
1 parent 2290bd5 commit 1cfa596

File tree

1 file changed

+29
-24
lines changed

1 file changed

+29
-24
lines changed

tree/rerooting.hpp

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,67 +15,72 @@ struct rerooting {
1515
int n_;
1616
std::vector<int> par, visited;
1717
std::vector<std::vector<std::pair<int, Edge>>> to;
18+
19+
// dp_subtree[i] = DP(root=i, edge (i, par[i]) is removed).
1820
std::vector<Subtree> dp_subtree;
21+
22+
// dp_par[i] = DP(root=par[i], edge (i, par[i]) is removed). dp_par[root] is meaningless.
1923
std::vector<Subtree> dp_par;
24+
25+
// dpall[i] = DP(root=i, all edges exist).
2026
std::vector<Subtree> dpall;
27+
2128
rerooting(const std::vector<std::vector<std::pair<int, Edge>>> &to_)
2229
: n_(to_.size()), par(n_, -1), visited(n_, 0), to(to_) {
2330
for (int i = 0; i < n_; ++i) dp_subtree.push_back(add_vertex(e(), i));
2431
dp_par = dpall = dp_subtree;
2532
}
2633

2734
void run_connected(int root) {
28-
if (visited[root]) return;
29-
visited[root] = 1;
35+
if (visited.at(root)) return;
36+
visited.at(root) = 1;
3037
std::vector<int> visorder{root};
3138

3239
for (int t = 0; t < int(visorder.size()); ++t) {
33-
int now = visorder[t];
34-
for (const auto &edge : to[now]) {
35-
int nxt = edge.first;
36-
if (visited[nxt]) continue;
40+
int now = visorder.at(t);
41+
for (const auto &[nxt, _] : to[now]) {
42+
if (visited.at(nxt)) continue;
3743
visorder.push_back(nxt);
38-
visited[nxt] = 1;
39-
par[nxt] = now;
44+
visited.at(nxt) = 1;
45+
par.at(nxt) = now;
4046
}
4147
}
4248

4349
for (int t = int(visorder.size()) - 1; t >= 0; --t) {
44-
int now = visorder[t];
50+
const int now = visorder.at(t);
4551
Children ch = e();
46-
for (const auto &edge : to[now]) {
47-
int nxt = edge.first;
48-
if (nxt == par[now]) continue;
49-
ch = rake(ch, add_edge(dp_subtree[nxt], nxt, edge.second));
52+
for (const auto &[nxt, edge] : to.at(now)) {
53+
if (nxt != par.at(now)) ch = rake(ch, add_edge(dp_subtree.at(nxt), nxt, edge));
5054
}
51-
dp_subtree[now] = add_vertex(ch, now);
55+
dp_subtree.at(now) = add_vertex(ch, now);
5256
}
5357

5458
std::vector<Children> left;
5559
for (int now : visorder) {
56-
int m = int(to[now].size());
60+
const int m = to.at(now).size();
5761
left.assign(m + 1, e());
5862
for (int j = 0; j < m; j++) {
59-
int nxt = to[now][j].first;
60-
const Subtree &st = (nxt == par[now] ? dp_par[now] : dp_subtree[nxt]);
61-
left[j + 1] = rake(left[j], add_edge(st, nxt, to[now][j].second));
63+
const auto &[nxt, edge] = to.at(now).at(j);
64+
const Subtree &st = (nxt == par.at(now) ? dp_par.at(now) : dp_subtree.at(nxt));
65+
left.at(j + 1) = rake(left.at(j), add_edge(st, nxt, edge));
6266
}
63-
dpall[now] = add_vertex(left.back(), now);
67+
dpall.at(now) = add_vertex(left.back(), now);
6468

6569
Children rprod = e();
6670
for (int j = m - 1; j >= 0; --j) {
67-
int nxt = to[now][j].first;
68-
if (nxt != par[now]) dp_par[nxt] = add_vertex(rake(left[j], rprod), now);
71+
const auto &[nxt, edge] = to.at(now).at(j);
72+
73+
if (nxt != par.at(now)) dp_par.at(nxt) = add_vertex(rake(left.at(j), rprod), now);
6974

70-
const Subtree &st = (nxt == par[now] ? dp_par[now] : dp_subtree[nxt]);
71-
rprod = rake(add_edge(st, nxt, to[now][j].second), rprod);
75+
const Subtree &st = (nxt == par.at(now) ? dp_par.at(now) : dp_subtree.at(nxt));
76+
rprod = rake(add_edge(st, nxt, edge), rprod);
7277
}
7378
}
7479
}
7580

7681
void run() {
7782
for (int i = 0; i < n_; ++i) {
78-
if (!visited[i]) run_connected(i);
83+
if (!visited.at(i)) run_connected(i);
7984
}
8085
}
8186

0 commit comments

Comments
 (0)