Skip to the content.

:heavy_check_mark: library/tree/ReRooting.hpp

Depends on

Verified with

Code

template <typename TREE, typename Data> class ReRooting {
    int n;
    TREE T;

  public:
    ReRooting(const TREE &T) : T(T), n(T.n) {}

    template <typename F1, typename F2>
    std::vector<Data> build(const F1 &score, const F2 &merge,
                            const Data &unit) {
        if (!~T.root)
            T.build(0);
        std::vector<Data> dp1(n, unit), dp2(n);
        for (int v : T.DFS)
            for (const auto &e : T.son(v)) {
                dp2[e.to] = score(dp1[e.to], e);
                merge(dp1[v], dp2[e.to]);
            }
        std::vector<Data> top(n, unit), res(n);
        for (int v : T.BFS) {
            Data now = (T.root == v ? unit : score(top[v], T.parent(v)));
            for (int to : T.son(v)) {
                top[to] = now;
                merge(now, dp2[to]);
            }
            res[v] = now;
            now = unit;
            for (int i = T.son(v).size() - 1; i >= 0; i--) {
                int to = T.son(v)[i];
                merge(top[to], now);
                merge(now, dp2[to]);
            }
        }
        return res;
    }
};
#line 1 "library/tree/ReRooting.hpp"
template <typename TREE, typename Data> class ReRooting {
    int n;
    TREE T;

  public:
    ReRooting(const TREE &T) : T(T), n(T.n) {}

    template <typename F1, typename F2>
    std::vector<Data> build(const F1 &score, const F2 &merge,
                            const Data &unit) {
        if (!~T.root)
            T.build(0);
        std::vector<Data> dp1(n, unit), dp2(n);
        for (int v : T.DFS)
            for (const auto &e : T.son(v)) {
                dp2[e.to] = score(dp1[e.to], e);
                merge(dp1[v], dp2[e.to]);
            }
        std::vector<Data> top(n, unit), res(n);
        for (int v : T.BFS) {
            Data now = (T.root == v ? unit : score(top[v], T.parent(v)));
            for (int to : T.son(v)) {
                top[to] = now;
                merge(now, dp2[to]);
            }
            res[v] = now;
            now = unit;
            for (int i = T.son(v).size() - 1; i >= 0; i--) {
                int to = T.son(v)[i];
                merge(top[to], now);
                merge(now, dp2[to]);
            }
        }
        return res;
    }
};
Back to top page