Skip to main content

斯坦纳树

Summary

最小斯坦纳树在带权无向图中连接给定的必选点,可以借助其他点降低总边权。必选点较少时,固定一个必选点作为最终的根,用状态压缩动态规划维护其余必选点的子集。转移在同一顶点合并两个子集,再沿最短路移动根。P6192 用 Floyd 预处理全源最短路,并用三角不等式保证移根转移可以原地更新。

参考资料​

简介​

给定边权非负的无向连通图 G=(V,E)G=(V,E) 和必选点集 S⊆VS\subseteq V,求包含 SS 的边权和最小的连通子图。删去环上的边不会增大边权和,因此可以取一棵树,称为 最小斯坦纳树(Minimum Steiner Tree)。

树中可以包含 SS 之外的点。例如,三个必选点两两之间的边权均为 22,另有一个点到三者的边权均为 11。只用必选点的最小代价为 44,加入这个点后只需 33。当 S=VS=V 时,问题退化为 最小生成树;当 SS 只有两个点时,答案就是两点间的 最短路 长度。

状态压缩动态规划​

任选一个必选点 rr,记其余必选点的集合为 TT。设 fA,uf_{A,u} 为连接子集 A⊆TA\subseteq T 和顶点 uu 的最小代价,答案为 fT,rf_{T,r}。空集的代价为 f∅,u=0f_{\varnothing,u}=0。

记 gA,xg_{A,x} 为在同一个点 xx 合并两个非空子集的最小代价:

gA,x=min⁡∅≠B⊊A(fB,x+fA∖B,x)g_{A,x}=\min_{\varnothing\ne B\subsetneq A}(f_{B,x}+f_{A\setminus B,x})

若 AA 只有一个点,则在该点令 gA,x=0g_{A,x}=0,其他位置为 ∞\infty。记 dx,ud_{x,u} 为 xx 到 uu 的最短路长度。合并后沿最短路移根:

fA,u=min⁡x∈V(gA,x+dx,u)f_{A,u}=\min_{x\in V}(g_{A,x}+d_{x,u})

对多点集合,取一棵所有叶子都属于 AA 或为 uu 的最优树。从 uu 沿唯一的分支走到首个属于 AA 的点或分叉点 xx,也可能一开始就有 x=ux=u。若 x∈Ax\in A,将 xx 单独分为一组;否则将 xx 的分支分为两组。两组子树与 uu 到 xx 的路径互不重边,所以转移能覆盖最优解。反过来,两棵子树与最短路的并集连通且包含 AA 和 uu,实际代价至多为转移式中的和。

用 Floyd 预处理 dd,再按掩码递增顺序处理子集。枚举划分时固定最低位所在的一侧。移根可原地更新:由三角不等式,经多个点移根不会优于直接移根。设 nn 为点数、kk 为必选点数,读入后的时间复杂度为 O(n3+n3k−1+n22k−1)O(n^3+n3^{k-1}+n^22^{k-1}),空间复杂度为 O(n2+n2k−1)O(n^2+n2^{k-1})。若图较稀疏,也可将 gA,xg_{A,x} 作为各点的初始距离,用多源 Dijkstra 完成移根。

例题​

给定一张 nn 个点、mm 条边的无向连通图,从中选出一个包含全部 kk 个必选点的连通子图,输出最小边权和。图中可能有重边和自环,且 n≤100n\le100,m≤500m\le500,k≤10k\le10,边权为 1∼1061\sim10^6。