問題はこちら
問題概要
解説
ある強連結成分を通るときはその強連結成分の全頂点を通るべきなので強連結成分分解してDAGにする.以降はDAGで解く.各頂点から新たに作った頂点
問題が最小費用流っぽい.最大化だったり,頂点にコストがあったりするが実は最小費用流のアルゴリズムで解ける.
最大化を最小化にするためにを
にする.負のコストをもつ辺ができるが,これは後で処理する.
頂点のコストは,頂点毎に以下のように頂点を2つ作る.この頂点を通るフローは必ず下図の2頂点の間の辺を通るのでこのように辺のコストに変換することができる.

複数回頂点を通っても最初の回しかコストが発生しない.これは上記の2頂点間に「容量
,コスト
の辺」と「容量
(実装では
でいい),コスト
の辺」を張ることで実現できる.優先的にコスト
の辺から使われるのでこの方法でよい.
こうしてできたグラフの頂点から頂点
へ流量
を流すときの最小コストが答えとなるが,負のコストをもつ辺があるので非負コストの辺のみからなるグラフの最小費用流に言い換える必要がある.
- 辺に適切に定数を足す.
- あらかじめ負のコストを持つ辺に最大までフローを流す.
- 最短距離を求めるアルゴリズムを用いてポテンシャルを初期化する(アリ本に説明アリ).
1は公式解説の方法であり,問題ごとに考える必要がある(ライブラリ化難しそう?).2は今回の問題だと全頂点に負のコストがあるので流すフローが多くなり間に合わない.3は負のコストがあるグラフの最短距離を求めるアルゴリズムであるBellman-Fordを用いるとかかり間に合わないが,グラフがDAGであることを利用してトポロジカル順にDPすることで最短距離が
で求められる.
提出プログラム
https://atcoder.jp/contests/abc214/submissions/25067496感想
Gより典型度高い.最小費用流の負辺除去は1の方法でやろうとするとこんがらがる.