F - Close Group Editorial
by
tatyam
このグラフの頂点集合を \(V\) 、 \(V\) の空でない部分集合を \(S\) 、 \(S\) による 誘導部分グラフ を \(G[S]\) 、
\(G[S]\) をこの問題の入力としたときの答えを \(f(S)\) とします。
求めたいものは \(f(V)\) ですが、 \(f(V)\) を求めるには \(f(S)\) の値が全て必要になるので、 \(f(S)\) の値を全て求めることを考えます。
\(f(S)\) は \(G[S]\) が完全グラフになっていれば \(f(S)=1\) 、そうでなければ、 \(\displaystyle \min_{T \subset S}f(T)+f(S \setminus T)\) によって求まります。
したがって、下位集合から順に \(f(S)\) を決定していくことができます。
計算量について考えてみましょう。
\(G[S]\) が完全グラフになっているかどうかは、 全ての \(S\) について \(O(2^N N^2)\) で求めることができます。
問題は \(\displaystyle \min_{T \subset S}f(T)+f(S \setminus T)\) の部分です。
\(T\) を \(V\) の部分集合の範囲で動かすと、全ての \(S\) について \(O(2^N \cdot 2^N)=O(4^N)\) になってしまいますが、 \(T\) が動くのは \(S\) の部分集合の範囲なので、
\[ \sum_{S \subset V} 2^{|S|}=3^N \]
より、全ての \(S\) について \(O(3^N)\) であることが分かります。
この計算は、 \(V\) の各要素が独立に
- \(S\) と \(T\) に含まれる
- \(S\) にのみ含まれる
- 両方含まれない
の \(3\) つを選べることからも分かります。
回答例 (C++) : https://atcoder.jp/contests/abc187/submissions/19103570
回答例 (Python) : https://atcoder.jp/contests/abc187/submissions/19103577
この問題は、
- 直接繋がれている \(2\) つの頂点は同じ色で塗って良い (違う色だったら辺を削除する)
- 直接繋がれていない \(2\) つの頂点は同じ色で塗ってはならない
とすると、補グラフの彩色数の問題であることがわかります。
グラフの彩色数の問題は \(O(2^NN)\) で解けるアルゴリズムが知られているので、この問題も \(O(2^NN)\) で解くことができます。
posted:
last update: