3198 < VPC TUATPC < Challenges | Aizu Online Judge
問題
$N \times N$ のグリッドがある。最初、そのうち $M$ マスが白マスで、それ以外が黒マスになっている。
グリッドに対して $Q$ 回の変更が行われる。各変更では 1 つのマスが指定され、そのマスの色を白黒反転させる。
各変更直後について、白マスに $N$ 個のコマを置くことで、各行・各列にコマがちょうど 1 つずつ置かれているようにできるか判定せよ。
制約
- $1 \leq N, M, Q \leq 5 \cdot 10^3$
考察
マッチングへの帰着
まず各行・列に対応する頂点を $N$ 個ずつ用意し、各白マス $(r, c)$ について、行側の頂点 $r$ と列側の頂点 $c$ を繋ぐ辺を張る。 するとこのグラフは $2N$ 頂点 $M$ 辺の二部グラフとなり、「コマの置き方」が「辺の選び方」と対応する。
そして問題文中の判定問題をこのグラフ上で解釈すると、「サイズ $N$ のマッチングが存在するか?」となる。 二部グラフの最大マッチングは、蟻本 P.195 や この記事 で述べられているように、最大流問題に帰着することで解くことができる。
高速化
しかし毎回愚直に最大流を求めていると間に合わない。 例えば Ford-Fulkerson のアルゴリズムでは、流量の最大値が $N$ なので、計算量は各クエリ $O(N(N+M+Q))$ となる(他のアルゴリズムでもほとんど同様)。
だがよく考えると、一度のクエリで最大流は高々 1 しか増減しない。 よって、前に流したフローをそのまま保持しておき、新たに流れたフローだけを求めることで、各クエリ $O(N+M+Q)$ で処理できる。
辺の削除
上の解法では、クエリ毎に辺の追加・削除を行う必要がある。追加は簡単だが、削除は少し考える必要がある。
まず消したい辺にフローが流れていない場合。この場合はその辺の容量を 0 にするだけでよい。
問題なのは消したい辺にフローが流れている場合で、この場合はこの辺を通るフローを消す必要がある。 今回は 2 部グラフなので、消したい辺が $uv$ である場合、このフローは常に $s \to u \to v \to g$ という形になっている1。よって辺 $su, uv, vg$ の流量を 0 にすればよい。
実装例
ac-library の MaxFlow は辺の流量・容量変更ができるので便利。
Run #4856232 < misteer < Solutions | Aizu Online Judge
|
|
-
もしもっと長い形をしている場合、流量を増やすことができる。例えば $s \to u' \to v' \to u \to v \to g$ なら、 $s \to u \to v' \to g$ に流すことができる。 ↩︎