这次介绍一个和最小生成树问题很类似的,名叫斯坦纳树的问题。
斯坦纳树有很多版本,这里我们说的是在图论中的斯坦纳树问题。
斯坦纳树(Steiner Tree)
定义有点复杂,容我先编个故事。
国家A和国家B在打仗,国家B无情地对国家A发动了地毯式轰炸,破坏了国家A城市间的所有道路。
为了尽快恢复,国家A列出了某些重要城市的名单,并研究出了修复每条道路的成本。如下图所示:
点代表城市,红色的点表示重要城市,边代表道路,边上的数字代表修复这条道路的成本。
现在问,如何在最小成本的情况下,修复道路,使得这些重要城市保持连通。比如上图中,按如下的选择,就可以达到最小的成本:
花费了10的成本,保证了重要城市的连通。
显然,我们最后的结果一定是棵树。但和最小生成树不同的是,我们不用保证所有店都连通,只需要保证部分点连通即可。这就是斯坦纳树问题。
定义:给一个连通无向图 ,和边权
。现在有一个点集
,求一个边权和最小的连通子图
,使得
。其中
就被称为斯坦纳树。
斯坦纳树也是一个NPH问题。
下面给出斯坦纳树的若干种解法。
暴力解法
在一个放弃思考的情况下,不难得出一个暴力的解法:直接枚举点子集,而后跑个最小生成树。这样做的复杂度是 ,其中
。
显然暴力做法在 很大,
很小的时候,是非常不理智的。鉴于只需要考虑
中的点,我们可以从动态规划的角度来解决。
动态规划
动态规划可以优美的做到 ,至于怎么实现,由于我主要想介绍容斥原理(我懒),所以就留给大家做练习啦。
提示一下:状态维护两维,一维是当前的集合,一维是当前的根。
容斥原理做法
特别提示:这里的介绍的容斥原理做法,只能解决边权都是 的情况,即
,无权图。
为了方便处理,我们需要将问题定义成判定型问题:
定义(无权斯坦纳树):给一个无向图 ,一个点子集
,和一个非负数
。我们的目的是判断是否存在一棵最多
条边的树
,使得
。
在本系列之前的文章中,我们用容斥原理统计了一个图的哈密顿圈的个数。
我们发现,相比研究圈(circle)、路径(path),通过研究游走(walk),来进行容斥是个更不错的主意。
于是,我们在这个问题中,也尝试通过游走来分析。
与之前的统计哈密顿圈不同,这里我们研究的游走是分支游走(branching walk)。
定义(分支游走):一个无向图 的分支游走定义为一个二元组
,其中
是一棵有根有序树(rooted ordered tree),并且
是一个同态(homomorphism)映射,即,
,有
。通常称
为
的长度。
举个例子,如下图所示:
数字表示了同态映射的对应关系
定理4:拿出 中的任意一点
。如果图
包含了一棵树
,并且
,
,当且仅当,图
包含一个从
开始的分支游走
,满足
,
。
定理4的是可以直观感受到的。
事实上,由于一棵树本身就是一个分支游走,所以如果一棵边数小于等于 的树覆盖了
中所有点,那么就存在了一个长度不超过
的分支游走(就是这棵树本身)。如果一个长度大小等于
的分支游走覆盖了
中所有点,那么这个分支游走的生成树就是边数不大于
的一棵斯坦纳树。
如下图所示:
红色的点是K中的点,图G中存在一个长度为7的分支游走,同样也存在一个边数为4的斯坦纳树。
有了定理4,我们就只需要统计,图中有多少从 开始,并且长度为
的分支游走,覆盖了
中所有点。
我们照着葫芦画瓢:
- 令全集
表示从
开始,长度为
的所有分支游走。
- 对
,令
,即访问了
的所有
中的分支游走。
- 我们的目标就是计算
根据定理2,我们有:
于是我们的目标就是计算 ,既是,从
出发,长度为
,不访问
中的任意一点的分支游走的方案数。
定理5:对于 ,
可以在
的复杂度内计算出来,其中
。
证明:我们使用动态规划来证明这个复杂度。令 。令
表示在
中从
出发,走长度为
的分支游走的方案数。有转移方程:
相当于枚举了 作为
的第一个儿子。如下图所示:
状态数是 ,转移数是
,所以求解
的复杂度就是
。
综上,我们便能通过统计分支游走的数量,来判断是否存在小于 的斯坦纳树。
定理6:无权斯坦纳树问题可以在 的时间内解决。