K小生成树: 生成树T删除一条边f并加入一条新边e的操作称为
交换。若交换后的图仍是一颗树,则此交换称为
可行交换。若生成树T可通过一次交换成为生成树T’,则称它们互为
邻树。对于生成树集合S,生成树T,若T不在S中,且在S中存在某生成树是T的邻树,称为T为S的邻树。 定理:设T1, T2, …… , TK为图的前k小生成树,则生成图集合{T1, T2, …… , TK}的邻树中的边权和最小者可作为第k+1小生成树(可能有边权和相同的情况)。 按这个定理设计算法,很难得到有满意的时间复杂度的算法。 下面讨论一个特例:
次小生成树(The second MST, 2-MST)
基本思想:首先求出最小生成树,记录权值之和为MST_NUM。然后枚举添加边(u,v),加上以后一定形成一个环,找到环上非(u,v)边的权值最大的边,把它删掉,计算当前生成树的权值之和,取所有枚举加边后生成树权值之和的最小值,就是次小生成树。
算法: 1.求出最小生成树T及其权值和MST_NUM,并标注在最小生成树上的边。 2.从每个顶点i为根,DFS遍历最小生成树,求出从i到j的路径上最大边的权值P(i, j)。 3.遍历每条不在最小生成树中的边(i,j),加上这条边,并删除环上最大边(P(i,j)),新的生成树权值之和为MST_NUM + w(i,j) - P[i][j],记录其最小值即可,时间复杂度为O(N^2)。求最小生成树可以用最简单的Prim即可,算法的瓶颈在第二步DFS遍历求路径上最大边需要O(n^2),用更好的算法是没有意义的。(
PS:对于每个边,实际上可以用LCA和预处理来得到环内最大边,这样复杂度就是O(ElogV),然后配合Kruskal复杂度可以降到O(ElogV), 留待以后学习。)
练习题:
POJ 1679 The Unique MST (MST是否唯一) 求出次小生成树,然后判断权值和是否等于最小生成树即可。
#include
#include
#include
#include
#include
#include
#include
#include
#include