最小斯坦纳树打印方案
阅读本文需要完全掌握上一篇文章《动态规划求解最小斯坦纳树》。
我们以求解“最小边权和”斯坦纳树为例进行演示。
【前情回顾】
动态规划求解最小斯坦纳树的过程,主要依靠两个步骤:合并子树,强行连通。
除了最初始的 d p [ 1 < < ( i − 1 ) ] [ t e r m i n a l [ i ] ] dp[1<<(i-1)][terminal[i]] dp[1<<(i−1)][terminal[i]]之外,其余的所有 d p dp dp 状态都是靠合并子树 + 强行连通产生的。
如何去求一个 d p [ S ] [ t e r m i n a l [ i ] ] dp[S][terminal[i]] dp[S][terminal[i]] 所表示的具体的最小斯坦纳树?只要遵循下面步骤:
1.求出 d p [ S ] [ t e r m i n a l [ i ] ] dp[S][terminal[i]] dp[S][terminal[i]] 是被谁转移的? 这个和 D i j k s t r a Dijkstra Dijkstra 求最短路时记录前驱结点相同。对于每个结点 i , i ∈ V i,i\in V i,i∈V,我们需要在强行连通操作中记录 i i i 是被谁转移的?将答案存在 f a [ S ] [ i ] fa[S][i] fa[S][i] 中。
if (dp[s][v] > dp[s][u] + w(u,v)) {
fa[s][v] = u;
q.push({
dp[s][v],v});
}
我们一直回溯下去(假设 v v v 是由 u u u 转移而来, u u u 是由 t t t 转移而来, ⋯ \cdots ⋯,最终一定存在一个点 x x x, d p [ S ] [ x ] dp[S][x] dp[S][x] 一定是由其自身的子树合并而来,即 f