Typical DP Contest R問題 : グラフ
問題. グラフ
頂点からなる単純有向グラフ が与えられる. の2つの有向道の頂点の和集合のサイズが最も大きいものを求めよ.
制約:
解法. 強連結成分分解 + 推移閉包 + 動的計画法
強連結成分分解を行いDAG上で2つの有向道を探す動的計画法をするところまでは分かったのですが,動的計画法の状態遷移など重要な箇所を埋めることが出来なかったので想定解法を参考にしました.解法は想定解法とまったく同じになってしまったのですが書きます.
Typical DP Contest ひとこと解法集 - Togetter
この問題で有向道 は頂点の重複を許すので,各 に対して同じ強連結成分に属する全ての頂点を から通って に戻ることができます.したがって,考える問題は を強連結成分分解して各強連結成分を1つの頂点に縮約してDAGにしたときに,各頂点にその強連結成分に属する頂点数を重み付けしたグラフ上で重み和最大の有向道を見つける問題に等しくなります.今後は,変換したグラフを ,頂点重みを として問題を考えることにして, の有向道の頂点の重み和をその有向道の重みと呼ぶことにします. はDAGなので頂点集合 はトポロジカルソートされているとします.
問題が1つの有向道を見つける問題ならば, を頂点 を終点とする重み最大の有向道の値として先頭から動的計画法を行えば求めることができるのですが,2つの有向道を考えると,2つの有向道が通る頂点に対してどう扱えばよいのかで難しくなります.
を互いに素で,終点がそれぞれ の部分有向道の各重みの和の最大値とします.部分有向道とはある有向道の頂点の部分列です.
下の例では各頂点の重みを1とします.部分有向道として と を考えると2つの重みの和は7となります. は例えば有向道 の部分列となっています.
に対して動的計画法をするのですが,扱いやすくするために に重み0の頂点 を加え, とします.これは, に対して終点が の部分有向道のみを考えることに対応します.
次に,上の例の部分有向道 のようなものを選択しやすくなるように, の推移閉包を考えます. の推移閉包とは推移性「 かつ ならば 」を満たすようになるまで に弧を加えたものです.これは,頂点 から へ有向道が存在するならば,弧 が存在するように弧を加えたことに等しくなります. に頂点 を加えて推移閉包したグラフを として説明します.
関数 と に対して,
のとき, ,
のとき,
と更新します.
最大関数の第2引数の というのは, のとき,終点 の部分有向道から に飛ぶ部分有向道となり終点を とする部分有向道と互いに素になります.同様に で考える部分有向道も互いに素になります.ここで, となる を考えると互いに素になるとは限らなくなるので注意が必要です.また,任意の に対して帰納法の仮定を満たすように遷移しているので,すべての互いに素な部分有向道を考えていることになります.
以上で求める答えは となります.
計算時間は,強連結成分分解とトポロジカルソートは , 推移閉包は ,動的計画法は なので全体で になります.
実装では初めに 時間で推移閉包をして,トポロジカルソート,動的計画法という流れで行っています.有向グラフに対しての推移閉包はフロイド・ワーシャル法のようにするとできます.
計算時間:
感想
rng_58さんの解法とソースコードを見て天才か!!とツッコんでしまった(本当に天才なので失礼).遷移を過不足無く書き出せるの難しい.