これは、動的計画法を使用して線形時間で解決できます。
N 個の頂点と N 個の辺を持つ連結グラフには、ちょうど 1 つのサイクルが含まれます。このサイクルを検出することから始めます (深さ優先探索の助けを借りて)。
次に、このサイクルのエッジをすべて削除します。このエッジに付随する 2 つの頂点はuとvです。このエッジの削除後、ツリーができました。根uを持つ根付き木として解釈します。
このツリーの動的プログラミングの再帰は、次のように定義できます。
- w 0 [k] = 0 (葉ノードの場合)
- w 1 [k] = vertex_cost (葉ノードの場合)
- w 0 [k] = w 1 [k+1] (1 つの子孫を持つノードの場合)
- w 1 [k] = vertex_cost + min( w 0 [k+1], w 1 [k+1]) (1 つの子孫を持つノードの場合)
- w 0 [k] = sum( w 1 [k+1], x 1 [k+1], ...) (分岐ノードの場合)
- w 1 [k] = vertex_cost + sum(min( w 0 [k+1], w 1 [k+1]), min( x 0 [k+1], x 1 [k+1]), .. .)
ここk
にノードの深さ (ルートからの距離) があります。w 0は、 wが「サブセット」にない場合のノードwから始まるサブツリーのコストです。w 1は、w が「サブセット」にある場合のノード w から始まるサブツリーのコストです。 「サブセット」で。
各ノードについて、 w 0とw 1の 2 つの値のみを計算する必要があります。しかし、サイクル上にあったノードの場合、4 つの値が必要です: w i,j 。ここで、ノードvが「サブセット」にない場合は i=0、ノードvが「サブセット」にある場合は i=1 、j=0 の場合現在のノードは「サブセット」にありません。現在のノードが「サブセット」にある場合は j=1。
「サブセット」の最適コストは、min( u 0,1 , u 1,0 , u 1,1 ) として決定されます。「サブセット」自体を取得するには、各サブツリー コストとともにバック ポインターを格納し、それらを使用してサブセットを再構築します。