斯坦纳树

给一张图,其中一些点称为关键点。

斯坦纳树的定义就是能覆盖关键点的连通子图,为什么叫连通子图,可以发现答案子图可以为一棵树,否则如果有环,可以删去环上任意一条边,新图也联通。

最小斯坦纳树#

Link

题意:给定一张带权无向图,其中有一些点是关键点,求连通子图的最小长度。

可以发现答案子图一定为一棵树,否则如果有环,可以删去环上任意一条边,新图也联通。

这是个 NP-hard 问题,可能没办法在多项式时间复杂度内(O(nk)O(nk))解决,考虑状压。

子图的状态肯定无法压进 dp,考虑将关键点的状态压进 dp。

由于答案是一棵树,可以设 fi,S 表示以 i 为根,且关键点覆盖状态为 S 的最小长度。

我们可以将以 i 为根的树分成两类:i 的度数为 1i 的度数大于 1

分讨:

  • i 的度数为 1,则这个点的转移来自于他唯一的连边,我们就考虑通过 i的相邻点来转移,设这个点为 j,则

fi,S=fj,S+disi,j

  • i 的度数大于 1,则可以将这个图分成 i 的若干个子树,就可以通过枚举子集转移:

fi,S=min{fi,T+fi,ST}

实现方面,对于第一种转移,可以想到最短路算法的松弛操作,将整张图松弛,先将整张图更新的点扔进队列,然后用第一种转移的转移式更新整张图的 f,通过最短路算法实现。

可以发现图是比较稀疏的,可以复活死去的 SPFA, 这个转移的时间复杂度卡满的话是 O(2knm),和枚举子集比起来你会惊奇发现这和枚举子集的时间复杂度差不多。

对于第二种转移,直接枚举子集,复杂度 O(3kn)

讲一下枚举子集的时间复杂度,之前一直不是很懂。

设集合大小为 T,则大小为 0 的子集个数为 Cn0,大小为 1 的子集个数为 Cn1...大小为 n 的子集个数为 Cnn

枚举的总复杂度就是 20×Cn0+21+Cn1+...2n+cnn=k=0n2kCnk=k=0n2k1nkCnk=(2+1)n=3n

最后 ans=min{fi,2k1}

游览计划#

可以发现这题很板,只是加了一个点权转边权和输出方案。

输出方案在每次转移时加一个 pre 数组,然后 dfs。

点权转边权可以考虑将第二个转移改成

fi,S=min{fi,T+fi,STvali}

因为两边我们都算了一次 i 节点,减了就行。

posted @   faith_xy  阅读(44)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示