MinCostFlow

It solves Minimum-cost flow problem.

Constructor

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

It creates a directed graph with $n$ vertices and $0$ edges. Cap and Cost are the type of the capacity and the cost, respectively.

Constraints

Complexity

add_edge

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

It adds an edge oriented from from to to with capacity cap and cost cost. It returns an integer $k$ such that this is the $k$-th edge that is added.

Constraints

Complexity

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);

Constraints

Complexity

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);

Let $g$ be a function such that $g(x)$ is the cost of the minimum cost $s-t$ flow when the amount of the flow is exactly $x$. $g$ is known to be piecewise linear. It returns $g$ as the list of the changepoints, that satisfies the followings.

Constraints

Let $x$ be the maximum cost among all edges.

Complexity

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();

Constraints

Complexity

Examples

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; }