D - 覚醒ノ高橋君 解説
by
maspy
読解から少し大変ですが,結局次の問題です:
- \(A\) 個のグラフが与えられる.それぞれ \(D=7\) 頂点以下である.辺には除去するためのコストが定まっている.これらをすべて木にするときのコストについて,小さい方から \(K\) 番目のものを求めよ.
以下の手順で解くことができます.
(1) 各町について,コストが \(0\), \(1\), \(\ldots\) であるような辺の除去方法を数える.
(2) 町全体で見たときに,コストが \(0, 1, \ldots\) であるような辺の除去方法を数える.
(3) \(K\) 番目のコストを出力する.
(3) は容易です.(1) の前提のもと (2) を解くことも,基本的な dp でできます(畳み込みの形になりますが,特別な高速化は要求されません).
(1) は,すべての部分木を列挙すればよいです.例えば次のような方法があります.
dfs で順に辺を残すか消すかを決めていく.その都度 unionfind などで連結性を確かめて,残す辺がサイクルを作らないようにする.
\(D\) 頂点のラベル付き木は全部で \(D^{D-2}\) 通りあることが知られており,これをすべて列挙する.例えばこの数え上げの証明に用いられる Prufer Code を使ってすべてのラベル付き木を生成する.
計算量は以下の通りです.
木の列挙:全体で\(O(A D^{D-2}\cdot poly(D))\)のような計算量.\(poly(D)\) は実装次第ですが, \(1\) からに \(D^3\) 程度になるのが普通だと思います.
数え上げ:\(cost_i\) の上限を \(C\) とする.町ごとのコストは \([0, C\cdot (D-1)(D-2)/2]\) に収まる.すべての dp テーブルのマージが \(O(A^2C^2D^4)\) 時間でできる.
この計算量でも AC 可能です(テストケースが弱いため,見積もりよりもかなり高速に解けると思います).
数え上げパートは,次のような高速化手段もあります.
- 「消す辺」のコストを考えると,町ごとのコストは \([0, C(D-1)]\) に収まり状態数が(\(D\) に関するオーダーレベルで)減る.
- 畳み込みに FFT などを用いる.
投稿日時:
最終更新: