最小 k 度限制生成树

原文地址:http://blog.163.com/surgy_han/blog/static/2079912702012112884113774/

所谓最小 k 度限制生成树,就是指有特殊的某一点的度不能超过k时的最小生成树。


简单思想:设特殊的那点为v0,先把v0,删除,求出剩下连通图的所有最小生成树,假如有m棵最小生成树,那么这些生成树必定要跟v0点相连,也就是说这棵生成树的v0点至少是m度的。若m>k,条件不成立,无法找到最小 k 度限制生成树;若m<=k,则枚举m到k的所有最小生成树,即一步步将v0点的度加1,直到v0点的度为k为止,则v0点度从m到k的(k - m + 1)棵最小生成树中最小的那棵即为答案。

具体步骤:

1. 先求出最小 m 度限制生成树:原图中去掉和 V0 相连的所有边(可以事先存两个图, Ray 的方法是一个邻接矩阵,一个邻接表,用方便枚举边的邻接表来构造新图),得到 m 个连通分量,则这 m  个连通分量必须通过 v0 来连接,所以,在图 G  的所有生成树中 dT(v0)≥m 。也就是说,当 k
2. 由最小 m 度限制生成树得到最小 m+1 度限制生成树;:连接和 V0 相邻的点 v ,则可以知道一定会有一个环出现(因为原来是一个生成树),只要找到这个环上的最大权边(不能与 v0 点直接相连)并删除,就可以得到一个 m+1 度限制生成树,枚举所有和 V0 相邻点 v ,找到替换后,增加权值最小的一次替换 (当然,找不到这样的边时,就说明已经求出) ,就可以求得 m+1 度限制生成树。。如果每添加一条边,都需要对环上的边一一枚举,时间复杂度将比较高(但这个题数据比较小,所以这样也没问题,事实上,直接枚举都能过这个 题),这里,用动态规划解决。设   Best(v) 为路径 v0—v 上与 v0 无关联且权值最大的边。定义 father(v) 为 v 的父结点,由此可以得到动态转移方程: Best(v)=max(Best(father(v)),ω(father(v),v)) ,边界条件为 Best[v0]=-∞ (因为我们每次寻找的是最大边,所以 -∞ 不会被考虑) ,Best[v’]=-∞| (v0,v’)∈E(T) 。


3. 当 dT(v0)=k 时停止(即当 V0 的度为 k 的时候停止),但不一定 k 的时候最优。

接下来说一下算法的实现:
采用并查集+ kruskal 代码量还少一点。
首先, 每个连通分量的的最小生成树可以直接用一个循环,循环着 Kruskal 求出。这里利用了联通分量间的独立性,对每个连通分量分别求最小生成树,和放在一起求,毫不影响。而且kruskral算法保证了各连通分量边的有序性。
找最小边的时候,上面讲的动态规划无疑是一种好方法,但是也可以这么做:
先走一个循环,但我们需要逆过来加边,将与v0关联的所有边从小到达排序,然后将各连通分量连接起来,利用并查集可以保证每个连通分量只有一条边与v0相连,由于边已经从小到达排序,故与每个连通分量相连的边就是每个连通分量与v0相连中的最小边。
然后求 m+1 度的最小生成树时,可以直接用 DFS ,最小生成树要一直求到 k 度,然后从中找出一个最优值。

你可能感兴趣的:(图论,acm学习资料)