把顶点V的度数<= K 称做度限制条件,把满足这一条件的生成树叫做度限制生成树,把权值和最小的度限制生成树称最小度限制生成树。
即求顶点V度数不超过K的最小生成树,令Hi 表示V的度数为 i 的最小生成树,此问题就变成求min{Hi , 1 <= i <= k}。
显然H1=T+{(0,x)},(0,x)时所有与v0关联的边中权值最小的。
在Hi-1上加入一条边(0,x),得到一个环,然后再删掉环中一条不与0关联的边,设为(xa,xb),这样就能得到一颗v0的度数为i的生成树,这样得到的生成树的权值和为cost(Hi-1)+cost(0,x)-cost(xa,xb),为了使权值最小,我们可以枚举x的值,删除时选取一条权值最大的。这样得到一颗v0的度数为i的最小生成树。
算法流程:
(1) 找{v1,…,vn}所有的连通块,求出每个连通块的最小生成树Ti.
(2) 在每个块中,选择v0相邻的最小边,得到Ht. Min = Ht,V = cost(Ht).
(3) 循环i = i+1 to k do
在Hi-1上选择“差额最小添删操作”,添加并删除一条边得到Hi,令v<-v+cost(添边)-cost(删边),若v<min,则令Min<-v;如果找不到“差额最小添删操作”则Break.
(4) 输出Min.
设不关联的顶点有一条权值无穷大(设为一个很大的值)的边,然后求出最小生成树,而不是森林,然后直接从(3)做起,前几次循环都将去掉一条无穷大的边。
查找“差额最小添删操作”只需用dfs找出来就行了。