mcf_graph
クラス · 最小費用流
template <class Cap, class Cost>
struct mcf_graph;
概要
最小費用流
非負コストの有向辺からなるグラフに対し、最小費用流と 流量・最小費用の折れ線を計算する。
テンプレートパラメータ
| 名前 | 説明 |
|---|---|
Cap |
容量の型 |
Cost |
コストの型 |
構築・破棄
| 名前 | 説明 | 計算量 |
|---|---|---|
(constructor) |
(1) 頂点数を指定せずデフォルト構築する (2) n頂点0辺のグラフを構築する |
$O(1)$ |
メンバ関数
| 名前 | 説明 | 計算量 |
|---|---|---|
size |
頂点数を返す | $O(1)$ |
add_edge |
容量と単位流量あたりのコストを持つ有向辺を追加する | 償却 $O(1)$ |
get_edge |
指定した辺の現在状態を返す | $O(1)$ |
edges |
全辺の現在状態を追加順で返す | 追加した辺数を $m$ として $O(m)$ |
flow |
(1) sからtへ流せるだけ流し、流量と最小費用を返す (2) sからtへ上限まで流し、流量と最小費用を返す |
(1) 流量を $F$、頂点数を $n$、辺数を $m$ として $O(F(n+m)\log(n+m))$ (2) 実際の流量を $F$、頂点数を $n$、辺数を $m$ として $O(F(n+m)\log(n+m))$ |
slope |
(1) 流量と最小費用の関係を表す折れ線を返す (2) 流量上限までの流量と最小費用の関係を表す折れ線を返す |
(1) 最大流量を $F$、頂点数を $n$、辺数を $m$ として $O(F(n+m)\log(n+m))$ (2) 実際の流量を $F$、頂点数を $n$、辺数を $m$ として $O(F(n+m)\log(n+m))$ |
メンバ型
| 名前 | 説明 | 計算量 |
|---|---|---|
edge |
追加した辺の現在状態 | 構築・各フィールドへのアクセスは $O(1)$ |
メンバの詳細
(constructor)
// (1)
mcf_graph();
// (2)
explicit mcf_graph(int n);
(1) 頂点数を指定せずデフォルト構築する
頂点数は未設定である。各演算を呼ぶ前に mcf_graph(n) で構築した値を代入する。
- 計算量: $O(1)$
(2) n頂点0辺のグラフを構築する
- パラメータ
n: 頂点数 - 計算量: $O(1)$
size
int size() const;
頂点数を返す
- 戻り値: 頂点数
- 計算量: $O(1)$
add_edge
int add_edge(int from, int to, Cap cap, Cost cost);
容量と単位流量あたりのコストを持つ有向辺を追加する
- パラメータ
from: 始点。$0\le from<n$ - パラメータ
to: 終点。$0\le to<n$ - パラメータ
cap: 非負の容量 - パラメータ
cost: 非負の単位コスト - 戻り値: 追加した辺のID
- 計算量: 償却 $O(1)$
get_edge
edge get_edge(int i);
指定した辺の現在状態を返す
- パラメータ
i:add_edgeが返した辺ID - 戻り値: i番目に追加した辺の現在状態
- 計算量: $O(1)$
edges
std::vector<edge> edges();
全辺の現在状態を追加順で返す
- 戻り値: 辺状態の列
- 計算量: 追加した辺数を $m$ として $O(m)$
flow
// (1)
std::pair<Cap, Cost> flow(int s, int t);
// (2)
std::pair<Cap, Cost> flow(int s, int t, Cap flow_limit);
(1) sからtへ流せるだけ流し、流量と最小費用を返す
- パラメータ
s: 始点 - パラメータ
t: 終点。sとは異なる頂点 - 戻り値: 流した量と最小費用の組
- 計算量: 流量を $F$、頂点数を $n$、辺数を $m$ として $O(F(n+m)\log(n+m))$
- 注意:
flowとslopeは合わせて1インスタンスにつき1回だけ呼べる。
(2) sからtへ上限まで流し、流量と最小費用を返す
- パラメータ
s: 始点 - パラメータ
t: 終点。sとは異なる頂点 - パラメータ
flow_limit: 流量の上限 - 戻り値: 流した量と最小費用の組
- 計算量: 実際の流量を $F$、頂点数を $n$、辺数を $m$ として $O(F(n+m)\log(n+m))$
- 注意:
flowとslopeは合わせて1インスタンスにつき1回だけ呼べる。
slope
// (1)
std::vector<std::pair<Cap, Cost>> slope(int s, int t);
// (2)
std::vector<std::pair<Cap, Cost>> slope(int s, int t, Cap flow_limit);
(1) 流量と最小費用の関係を表す折れ線を返す
最初の要素は $(0,0)$。連続する3点が同一直線上にならないよう圧縮される。 最後の要素は最大流量とその最小費用である。
- パラメータ
s: 始点 - パラメータ
t: 終点。sとは異なる頂点 - 戻り値: 折れ線の頂点を流量・最小費用の組で並べた列
- 計算量: 最大流量を $F$、頂点数を $n$、辺数を $m$ として $O(F(n+m)\log(n+m))$
- 注意:
flowとslopeは合わせて1インスタンスにつき1回だけ呼べる。
(2) 流量上限までの流量と最小費用の関係を表す折れ線を返す
最初の要素は $(0,0)$。連続する3点が同一直線上にならないよう圧縮される。 最後の要素は最大流量とflow_limitの小さい方に対する最小費用である。
- パラメータ
s: 始点 - パラメータ
t: 終点。sとは異なる頂点 - パラメータ
flow_limit: 流量の上限 - 戻り値: 折れ線の頂点を流量・最小費用の組で並べた列
- 計算量: 実際の流量を $F$、頂点数を $n$、辺数を $m$ として $O(F(n+m)\log(n+m))$
- 注意:
flowとslopeは合わせて1インスタンスにつき1回だけ呼べる。
edge
struct edge;
追加した辺の現在状態
from、to、容量 cap、現在の流量 flow、 単位流量あたりのコスト cost を保持する。
- 計算量: 構築・各フィールドへのアクセスは $O(1)$
| メンバ | 説明 |
|---|---|
to |
辺の始点と終点 |
flow |
辺の容量と現在の流量 |
cost |
単位流量あたりのコスト |
edge |
辺の状態を構築する |