MinCostFlow

Minimum-cost flow problemを扱うライブラリです。

コンストラクタ

var graph = init_mcf_graph[Cap, Cost](int n)

$n$ 頂点 $0$ 辺のグラフを作る。Capは容量の型、Costはコストの型

制約

計算量

add_edge

graph.add_edge(src:int, dst:int, cap:Cap, cost:Cost):int

fromからtoへ最大容量cap, コストcostの辺を追加する。何番目に追加された辺かを返す。

制約

計算量

min_cost_max_flow

(1) graph.flow(s:int, t:int):(Cap, Cost)
(2) graph.flow(s:int, t:int, flow_limit:Cap):(Cap, Cost)

$s$ から $t$ へ流せるだけ流し、その流量とコストを返す。

制約

計算量

min_cost_slope

graph.slope(s:int, t:int):seq[(Cap, Cost)]
graph.slope(s:int, t:int, flow_limit:Cap):seq[(Cap, Cost)]

帰り値に流量とコストの関係の折れ線が入る。全ての $x$ について、流量 $x$ の時の最小コストを $g(x)$ とすると、$(x, g(x))$ は帰り値を折れ線として見たものに含まれる。

制約

辺のコストの最大を $x$ として

計算量

$F$を流量、$m$を追加した辺の本数として

edges

type edge_info[Cap, Cost] =
  src, dst:int
  cap, flow: Cap
  cost:Cost

(1) graph.get_edge(int i):edge_info[Cap, Cost]
(2) graph.edges():seq[edge_info[Cap, Cost]]

$m$ を追加された辺数として

制約

計算量

使用例

AC code of https://atcoder.jp/contests/practice2/tasks/practice2_e

include atcoder/header import atcoder/mincostflow let n, k = nextInt() var g = initMCFGraph[int,int](n * 2 + 2) let (s, t) = (n * 2, n * 2 + 1) let BIG = 1000000000 g.add_edge(s, t, n * k, BIG) for i in 0..<n: g.add_edge(s, i, k, 0) g.add_edge(n + i, t, k, 0) for i in 0..<n: for j in 0..<n: let a = nextInt() g.add_edge(i, n + j, 1, BIG - a) var result = g.flow(s, t, n * k) echo n * k * BIG - result[1] var grid = newSeqWith(n, '.'.repeat(n)) let es = g.edges() for e in es: if e.src == s or e.dst == t or e.flow == 0: continue grid[e.src][e.dst - n] = 'X' for i in 0..<n: echo grid[i]