sotanishy's competitive programming library

sotanishy's code snippets for competitive programming

View the Project on GitHub sotanishy/cp-library-cpp

:warning: Monge Shortest Path
(dp/monge_shortest_path.hpp)

Description

Monge な辺重みを持つ完全 DAG 上の最短距離を求める.この問題は LARSCH algorithm によって $O(N)$ 時間で解けるが,この実装ではより実装が簡単で定数倍高速な $O(N \log N)$ 時間の簡易版 LARSCH algorithm を用いている.

Reference

Code

#pragma once
#include <limits>
#include <vector>

template <typename T, typename F>
std::vector<T> monge_shortest_path(int n, const F& cost) {
    const T INF = std::numeric_limits<T>::max() / 2;
    std::vector<T> dist(n, INF);
    dist[0] = 0;
    std::vector<int> amin(n);

    auto update = [&](int i, int k) {
        if (i <= k) return;
        auto nd = dist[k] + cost(k, i);
        if (nd < dist[i]) {
            dist[i] = nd;
            amin[i] = k;
        }
    };

    auto dfs = [&](auto& dfs, int l, int r) -> void {
        if (r - l == 1) return;
        int m = (l + r) / 2;
        for (int k = amin[l]; k <= amin[r]; ++k) update(m, k);
        dfs(dfs, l, m);
        for (int k = l + 1; k <= m; ++k) update(r, k);
        dfs(dfs, m, r);
    };

    dfs(dfs, 0, n - 1);
    return dist;
}
#line 2 "dp/monge_shortest_path.hpp"
#include <limits>
#include <vector>

template <typename T, typename F>
std::vector<T> monge_shortest_path(int n, const F& cost) {
    const T INF = std::numeric_limits<T>::max() / 2;
    std::vector<T> dist(n, INF);
    dist[0] = 0;
    std::vector<int> amin(n);

    auto update = [&](int i, int k) {
        if (i <= k) return;
        auto nd = dist[k] + cost(k, i);
        if (nd < dist[i]) {
            dist[i] = nd;
            amin[i] = k;
        }
    };

    auto dfs = [&](auto& dfs, int l, int r) -> void {
        if (r - l == 1) return;
        int m = (l + r) / 2;
        for (int k = amin[l]; k <= amin[r]; ++k) update(m, k);
        dfs(dfs, l, m);
        for (int k = l + 1; k <= m; ++k) update(r, k);
        dfs(dfs, m, r);
    };

    dfs(dfs, 0, n - 1);
    return dist;
}
Back to top page