前置技能:
- 知道怎么搞出最小生成树(即K算法和P算法)
这里给出一些定义:
- 定义次小生成树为所有生成树中第二小的(可能不止一个)
- 有用边为原最小生成树的任意边
- 无用边为不在原最小生成树的任意边
所以推理得出以下结论
1. 至少有一条边在次小生成树中而不在最小生成树中
2. 次小生成树肯定是某条无用边的对应最小生成树
首先**答案肯定不是某条有用边的对应最小生成树,由结论1我们可以得到某条在次小生成树而不在最小生成树上的边,我们称它为Z
显然Z是条无用边,因为他不在原最小生成树上
因为我们已经把它加入到答案中,于是答案的边集和原最小生成树的边集必定是不同的,于是我们剩下只需要最小化Z所在生成树的权值(即找到Z的对应最小生成树),这棵生成树就是答案啦
3. 任意无用边的对应最小生成树肯定不是一开始求的原最小生成树
接下来便是生成次小生成树的方法 这里给出两种
方法一------- 暴力(万物皆可暴力)
1.生成最小生成树
2.枚举删去最小生成树的边求解 (时间复杂度O(nmlogm))
方法二------- 高级方法
1.设max[i][j]表示在最小生成树中任意两个点i,j的唯一路径中权值最大的那条边的权值
(max[][]可由O(n*n)求出)
2.枚举不再原最小生成树上的边map[i][j],加入边map[i][j]替换为max[i][j]的边
求出当前生成树的权值Ans Ans=Ans+map[i][j]-max[i][j]
3.不断枚举更新生成树的最小值,即可求出次小生成树 ( 时间复杂度为O(n*n+m))