かしのブログ

競技プログラミングとか

第二回 アルゴリズム実技検定 O - 可変全域木

問題

 N頂点 M辺の重みつき単純連結無向グラフが与えられる。 辺 iは頂点 A_i B_iを結び、重みは C_iである。 辺 1から Mそれぞれについて、その辺を含む最小の重みの全域木を求める。

atcoder.jp

考察

与えられた連結グラフの最小の重みの全域木とその重みを求める。 この全域木に含まれる辺はこれで求められる。

それ以外の辺 iについて考える。 作った全域木に辺 iを追加すると、全域木上の頂点 A_i B_iを結ぶパスと辺 iで閉路ができ、この閉路上の任意の辺を1つ除くと再び全域木ができることがわかる。 取り除く辺は辺 i以外の閉路上の辺のうち、もっとも重みが大きいものでよい(証明を後述)。

閉路上のもっとも重みの大きい辺を見つけるにはLowest Common Ancestorのアルゴリズムが使える。計算量は \mathcal{O}(N \log N)になる。

証明

[補題]  iを含むグラフ上の最小全域木は、最小全域木 \mathcal{T}に辺 iを追加し、 \mathcal{T}での頂点 A_i B_iのパス上の辺のうちもっとも重みの大きい辺を除いたグラフと一致する

クラスカル法では、連結グラフの重みの小さい辺から順番に、現在作っている全域木に追加しても閉路を作らないもののみを追加することで最小全域木 \mathcal{T}を構築する。

頂点 A_i B_iを結ぶ、 \mathcal{T}に含まれない辺 iについて考える。  \mathcal{T}で頂点 a bのパス上の辺は e_{p(1)}, e_{p(2)}, \cdots, e_{p(k)}で、  C_{p(1)} \leq C_{p(2)} \leq \cdots \leq C_{p(k)}を満たす。

頂点 A_i B_iを辺 iで結んだ状態からクラスカル法を用いて、この条件下での最小全域木 \mathcal{T}^\primeを求める。 辺 e_{p(1)}, e_{p(2)}, \cdots, e_{p(k)}は、番号 p(1), p(2), \cdots, p(k)の順に追加されるが、 e_{p(k)}を追加すると閉路ができるため、 e_{p(k)}は追加されない。 また、頂点 A_i B_iのパス上以外の辺は、これに影響されないので、 \mathcal{T}と同じ辺を使うことができる。

以上より、 \mathcal{T}^\primeは、 \mathcal{T}に辺 iを追加し辺 e_{p(k)}を除いたものと一致する。よって題意は示された。

実装

atcoder.jp