Nyaan's Library

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

View on GitHub

:heavy_check_mark: monge グラフ上の最短路
(dp/monge-shortest-path.hpp)

Required by

Verified with

Code

#pragma once

#include <functional>
#include <vector>
using namespace std;

// https://noshi91.hatenablog.com/entry/2023/02/18/005856
// 辺コストが monge である DAG の 0 - i 最短路
template <typename T>
vector<T> monge_shortest_path(int N, const function<T(int, int)>& f) {
  T INF = (T{1} << (sizeof(T) * 8 - 2)) - 1;
  vector<T> dp(N + 1, INF);
  vector<int> x(N + 1, 0);
  auto check = [&](int from, int to) {
    if (from >= to) return;
    T cost = f(from, to);
    if (dp[from] + cost < dp[to]) dp[to] = dp[from] + cost, x[to] = from;
  };
  auto dfs = [&](auto rc, int l, int r) -> void {
    if (l + 1 >= r) return;
    int m = (l + r) / 2;
    for (int i = x[l]; i <= x[r]; i++) check(i, m);
    rc(rc, l, m);
    for (int i = l + 1; i <= m; i++) check(i, r);
    rc(rc, m, r);
  };
  dp[0] = 0, check(0, N), dfs(dfs, 0, N);
  return dp;
}

/**
 * @brief monge グラフ上の最短路
 */
#line 2 "dp/monge-shortest-path.hpp"

#include <functional>
#include <vector>
using namespace std;

// https://noshi91.hatenablog.com/entry/2023/02/18/005856
// 辺コストが monge である DAG の 0 - i 最短路
template <typename T>
vector<T> monge_shortest_path(int N, const function<T(int, int)>& f) {
  T INF = (T{1} << (sizeof(T) * 8 - 2)) - 1;
  vector<T> dp(N + 1, INF);
  vector<int> x(N + 1, 0);
  auto check = [&](int from, int to) {
    if (from >= to) return;
    T cost = f(from, to);
    if (dp[from] + cost < dp[to]) dp[to] = dp[from] + cost, x[to] = from;
  };
  auto dfs = [&](auto rc, int l, int r) -> void {
    if (l + 1 >= r) return;
    int m = (l + r) / 2;
    for (int i = x[l]; i <= x[r]; i++) check(i, m);
    rc(rc, l, m);
    for (int i = l + 1; i <= m; i++) check(i, r);
    rc(rc, m, r);
  };
  dp[0] = 0, check(0, N), dfs(dfs, 0, N);
  return dp;
}

/**
 * @brief monge グラフ上の最短路
 */
Back to top page