@@ -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