icpc_library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub ebi-fly13/icpc_library

:heavy_check_mark: Lowest Common Ancestor
(tree/LowestCommonAncestor.hpp)

説明

木のLCAをダブリングで求める。

コンストラクタ

LowestCommonAncestor(std::vector<std::vector<int>> g, int root = 0)

木グラフ g と root ノード番号を与えてLCAの前計算をする。デフォルトで root は頂点 0

la(int u, int k)

頂点 u から 親方向に k だけ上った頂点を返す。

lca(int u, int v)

頂点 u, v のLCAを返す。

distance(int u, int v)

頂点 u, v の距離を返す。

Depends on

Verified with

Code

#pragma once

#include "../template/template.hpp"

namespace lib {

struct LowestCommonAncestor {
    int n;
    std::vector<std::vector<int>> table;
    std::vector<int> depth;
    int log = 25;

    LowestCommonAncestor(const std::vector<std::vector<int>> &gh, int root = 0)
        : n(gh.size()) {
        table = std::vector(log, std::vector<int>(n, -1));
        depth.assign(n, 0);
        auto dfs = [&](auto &&self, int v) -> void {
            for (auto nv : gh[v]) {
                if (table[0][v] == nv) continue;
                table[0][nv] = v;
                depth[nv] = depth[v] + 1;
                self(self, nv);
            }
        };
        dfs(dfs, root);
        table[0][root] = root;
        rep(i, 0, log - 1) {
            rep(v, 0, n) {
                table[i + 1][v] = table[i][table[i][v]];
            }
        }
    }

    int la(int u, int k) const {
        if (depth[u] < k) return -1;
        rrep(i, 0, log) {
            if ((k >> i) & 1) {
                u = table[i][u];
            }
        }
        return u;
    }

    int lca(int u, int v) const {
        if (depth[u] < depth[v]) std::swap(u, v);
        u = la(u, depth[u] - depth[v]);
        if (u == v) return u;
        rrep(i, 0, log) {
            if (table[i][u] != table[i][v]) {
                u = table[i][u];
                v = table[i][v];
            }
        }
        return table[0][u];
    }

    int distance(int u, int v) const {
        int l = lca(u, v);
        return depth[u] + depth[v] - 2 * depth[l];
    };
};

}  // namespace lib
#line 2 "tree/LowestCommonAncestor.hpp"

#line 2 "template/template.hpp"

#include <bits/stdc++.h>

#define rep(i, s, n) for (int i = (int)(s); i < (int)(n); i++)
#define rrep(i, s, n) for (int i = (int)(n)-1; i >= (int)(s); i--)
#define all(v) v.begin(), v.end()

using ll = long long;
using ld = long double;
using ull = unsigned long long;

template <typename T> bool chmin(T &a, const T &b) {
    if (a <= b) return false;
    a = b;
    return true;
}
template <typename T> bool chmax(T &a, const T &b) {
    if (a >= b) return false;
    a = b;
    return true;
}

namespace lib {

using namespace std;

}  // namespace lib

// using namespace lib;
#line 4 "tree/LowestCommonAncestor.hpp"

namespace lib {

struct LowestCommonAncestor {
    int n;
    std::vector<std::vector<int>> table;
    std::vector<int> depth;
    int log = 25;

    LowestCommonAncestor(const std::vector<std::vector<int>> &gh, int root = 0)
        : n(gh.size()) {
        table = std::vector(log, std::vector<int>(n, -1));
        depth.assign(n, 0);
        auto dfs = [&](auto &&self, int v) -> void {
            for (auto nv : gh[v]) {
                if (table[0][v] == nv) continue;
                table[0][nv] = v;
                depth[nv] = depth[v] + 1;
                self(self, nv);
            }
        };
        dfs(dfs, root);
        table[0][root] = root;
        rep(i, 0, log - 1) {
            rep(v, 0, n) {
                table[i + 1][v] = table[i][table[i][v]];
            }
        }
    }

    int la(int u, int k) const {
        if (depth[u] < k) return -1;
        rrep(i, 0, log) {
            if ((k >> i) & 1) {
                u = table[i][u];
            }
        }
        return u;
    }

    int lca(int u, int v) const {
        if (depth[u] < depth[v]) std::swap(u, v);
        u = la(u, depth[u] - depth[v]);
        if (u == v) return u;
        rrep(i, 0, log) {
            if (table[i][u] != table[i][v]) {
                u = table[i][u];
                v = table[i][v];
            }
        }
        return table[0][u];
    }

    int distance(int u, int v) const {
        int l = lca(u, v);
        return depth[u] + depth[v] - 2 * depth[l];
    };
};

}  // namespace lib
Back to top page