对于一个无向带边权连通图G(V,E),我们一定能从中提取出最小生成树,那么对于次小生成树该如何获取?记图G中有效生成树集合为Z,而T为G的中的总权重最小的生成树,那么G\{T}中总权重最小的树就是次小生成树。
我们不妨先考虑这样一个问题,记T为图G中的最小生成树,由于生成树由|V|-1条边唯一决定,因此我们可以认为T代表的是最小生成树中的边组成的集合。很容易发现次小生成树必然包含E\T的某条边,我们可以枚举每一条E\T中的边e,并将e的两端点合并,在此基础上运行Kruskal或者Prim算法,找到新的生成树,并将e加入生成树,就得到了所有含e的生成树中的权重最小的生成树,我们之后称这种树为含e最小生成树。之后寻找这些树中权重最小的生成树即为次小生成树,这个方法是可行的,但是效率非常感人,时间复杂度二者均为O((|E|-|V|)*|V|log2(|V|))。
事实上可以在O(|E|log2(|V|))时间复杂度内找到次小生成树。
首先我们要找到最小生成树T。之后我们枚举E\T中的每一条边e,将e加入T中,此时T内必定存在一个环,且环包含e(|V|边连通图必定带一个环),为了使T再次成为一株合法的生成树,我们需要移除环中的某条边,显然我们不应该移除e(否则何必要加入呢?),我们要移除的是环中权重最大的边t,之后T再次成为了一株生成树T‘。能保证得到的树T‘是含e最小生成树,事实上我们在合并了e的两个端点后得到了新的图G‘,图G‘中的最小生成树必定为T‘\{e},这是由于我们在其上运行Kruskal算法时,所有权重小于t的边会照旧被选入,而在所有权重小于t的边处理完成后,原本e所在的环也只缺少一条边t,由于生成树中不允许有环,因此t不会被加入,到此孤立的连通子图之间的联系与在G上建立最小生成树无二。因此T‘\{e}是G‘上的最小生成树。若T‘不是G中含e最小生成树,则存在含e生成树F‘,但是F‘\e也是G‘的一个生成树,这意味着F‘\e的总权重小于T‘\e,这与T‘\e是G‘的最小生成树相悖,假设不成立,故T‘是G中含e最小生成树。
那么如何在O(|E|log2(|V|))时间复杂度内完成上面所有的操作呢,我们只要对于每条边e,能够以log2(|V|)时间复杂度快速计算在最小生成树中e的两端点之间路径上的最大的边即可。这样的算法是存在的,可以利用LCT(动态树)实现。
寻找最小生成树的时间复杂度为O(|V|log2(|V|)),而在最小生成树上建立LCT的建立时间复杂度为O(|V|log2(|V|)),为E\T上所有边e寻找含e最小生成树的时间复杂度为O((|E|-|V|)log2(|V|)),因此总的时间复杂度为O(|E|log2(|V|)。