斯坦纳树

一些背景

问题引入:

给出一个图 \(G=(V,E)\)\(V\) 表示结点,\(E\) 表示边),以及 \(V\) 的一个子点集 \(S\)。现在要求选出一个 \(G\) 的子图 \(G'=(V',E')\),满足

  1. \(S\subseteq V'\)

  2. \(G'\) 为连通图

  3. \(E'\) 的边权和最小

换句话说,就是给出一个图,以及图上的一些关键结点,要求你求出这些关键结点的最短连通图


显然,首先这个选出来的图一定是一棵树

一般来说,题目给定的关键结点的个数会很少,因此我们考虑状压

我们设 \(f[i][S]\) 表示以 \(i\) 为根时,包含 \(S\) 中的关键结点的最短连通图

因此有以下转移:

\[f[i][S] = \min\{f[i][T]+f[i][S-T]\}\ (T \in S) \]

\[f[i][S] = \min\{f[j][S] +w_{j, i}\} \]

显然,我们需要完成第一个转移,才能进行第二个转移

而第二个转移正是最短路的转移方程,因此我们可以直接跑一遍 \(\text{dijkstra}\)

时间复杂度为 \(O(3^kn+2^k m\log m)\)

代码


例题:[WC2008]游览计划

边权变点权,但这并不妨碍我们

写出转移方程:

\[f[i][S] = \min\{f[i][T] + f[i][S - T] - val[i]\} \]

\[f[i][S] = \min\{f[j][S] + val[i]\} \]

正常跑一遍斯坦纳树,注意记录最优方案的转移点,输出方案时进行回溯即可

代码

posted @ 2022-08-12 14:58  zuytong  阅读(35)  评论(0编辑  收藏  举报