356. 次小生成树 - AcWing题库
给定一张 N 个点 M 条边的无向图,求无向图的严格次小生成树。
设最小生成树的边权之和为 sum,严格次小生成树就是指边权之和大于 sum 的生成树中最小的一个。
输入格式
第一行包含两个整数 N 和 M。
接下来 M 行,每行包含三个整数 x,y,z,表示点 x 和点 y 之前存在一条边,边的权值为 z。
输出格式
包含一行,仅一个数,表示严格次小生成树的边权和。(数据保证必定存在严格次小生成树)
数据范围
N≤105,M≤3×105
1≤x,y≤N
0≤z≤106
输入样例:
5 6
1 2 1
1 3 2
2 4 3
3 5 4
3 4 3
4 5 6
输出样例:
11
解析:
先求出任意一棵最小生成树,设边权之和为sum。我们称在这棵最小生成树中的N-1条边为“树边”,其他M-N+1条边为”非树边“。
把一条非树边(x,y,z)添加到最小生成树中,会与树上 x,y 之间的路径一起形成一个环。设树上 x,y 之间的路径上的最大边权为 val1 ,严格次打边权为 val2(val1>val2)。
若 z>val1,则把 val1 对应的那条边替换成 (x,y,z)这条边,就得到了严格次小生成树的一个候选答案,边权之和为 sum-val1+z。
若 z=val1,则把 val2 对应的那条边替换成 (x,y,z)这条边,就得到了严格次小生成树的一个候选答案,边权之和为 sum-val2+z。
枚举每条非树边,添到最小生成树中,计算出上述所有”候选答案“。在候选答案中取最小值就得到了整张无向图的严格次小生成树。因此,我们要解决的主要问题是:如何快速求出一条路径上最大边权与严格次大边。
可以用树上倍增算法来进行预处理。设F[x,k]表示 x 的 2^k 辈祖先,G[x,k,0] 与 G[x,k,1] 分别表示从 x 到 F[x,k] 的路径上的最大边权和严格次大边权(最大边权不等于次大边权)。于是任意 k 属于[1,logN] 有:
F[x,k]=F[F[x,k-1]][k-1]
G[x,k,0]=max(G[x,k-1,0],G[F[x,k-1],k-1,0])
对于 G[x,k,1]:
G[x,k,1]=max(G[x,k-1,1],G[F[x,k-1],k-1,1]),G[x,k-1,0]=G[F[x,k-1],k-1,0]
G[x,k,1]=max(G[x,k-1,0],G[F[x,k-1],k-1,1]),G[x,k-1,0] G[x,k,1]=max(G[x,k-1,1],G[F[x,k-1],k-1,0]),G[x,k-1,0]>G[F[x,k-1],k-1,0]
当 k=0 时,有初值:
F[x,0]=fa(x)
G[x,0,0]=edge(x,fa(x))
G[x,0,1]=负无穷
时间复杂度为O(MlogN)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include