MinCostFlow

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

コンストラクタ

mcf_graph<Cap, Cost> graph(int n);

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

制約

計算量

add_edge

int graph.add_edge(int from, int to, Cap cap, Cost cost);

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

制約

計算量

min_cost_max_flow

(1) pair<Cap, Cost> graph.flow(int s, int t);
(2) pair<Cap, Cost> graph.flow(int s, int t, Cap flow_limit);

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

制約

計算量

min_cost_slope

vector<pair<Cap, Cost>> graph.slope(int s, int t);
vector<pair<Cap, Cost>> graph.slope(int s, int t, Cap flow_limit);

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

制約

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

計算量

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

edges

struct edge<Cap, Cost> {
    int from, to;
    Cap cap, flow;
    Cost cost;
};

(1) mcf_graph<Cap, Cost>::edge graph.get_edge(int i);
(2) vector<mcf_graph<Cap, Cost>::edge> graph.edges();

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

制約

計算量

使用例

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

#include <atcoder/mincostflow> #include <iostream> using namespace std; using namespace atcoder; const long long BIG = 1'000'000'000; int main() { int n, k; cin >> n >> k; /** * generate (s -> row -> column -> t) graph * i-th row correspond to vertex i * i-th col correspond to vertex n + i **/ mcf_graph<int, long long> g(2 * n + 2); int s = 2 * n, t = 2 * n + 1; // we can "waste" the flow g.add_edge(s, t, n * k, BIG); for (int i = 0; i < n; i++) { g.add_edge(s, i, k, 0); g.add_edge(n + i, t, k, 0); } for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { long long a; cin >> a; g.add_edge(i, n + j, 1, BIG - a); } } auto result = g.flow(s, t, n * k); cout << 1LL * n * k * BIG - result.second << endl; vector<string> grid(n, string(n, '.')); auto edges = g.edges(); for (auto e : edges) { if (e.from == s || e.to == t || e.flow == 0) continue; grid[e.from][e.to - n] = 'X'; } for (int i = 0; i < n; i++) { cout << grid[i] << endl; } return 0; }