この問題は、最小和部分列問題とほとんど同じであり、動的計画法によって同様の方法で解くことができます。
DF 検索を使用して、次の配列を計算します。
dw1[i] = minimum sum achievable by only using node i and its descendants.
pw1[i] = predecessor of node i in the path found for dw1[i].
dw2[i] = second minimum sum achevable by only using node i and its descendants,
a path that is edge-disjoint relative to the path found for dw1[i].
これらを計算できたら、min(dw1[k], dw1[k] + dw2[k])
すべて引き継いでk
ください。これは、パスが次の基本的な形状のいずれかを取るためです。
k k
| or / \
| / \
|
これらはすべて、私たちが取っている金額によってカバーされています。
dw1 の計算
ルート ノードから DFS を実行します。DFS で、現在のノードとその親ノードを追跡します。各ノードで、その子が であると仮定しますd1, d2, ... dk
。それからdw1[i] = min(min{dw1[d1] + cost[i, d1], dw1[d2] + cost[i, d2], ..., dw1[dk] + cost[i, dk]}, min{cost[i, dk]})
。dw1[i] = 0
葉ノードに設定します。pw1[i]
選択した前任者で更新することを忘れないでください。
dw2 の計算
ルート ノードから DFS を実行します。に対して行ったのと同じことを行いますdw1
。ただし、ノードi
からその子の 1 つに移動する場合k
は、更新するdw2[i]
場合にのみpw1[i] != k
. ただし、すべての子に対して関数を再帰的に呼び出します。擬似コードでは次のようになります。
df(node, father)
dw2[node] = inf
for all children k of node
df(k, node)
if pw1[node] != k
dw2[node] = min(dw2[node], dw1[k] + cost[node, k], cost[node, k])