📅  最后修改于: 2023-12-03 14:58:24.914000             🧑  作者: Mango
这是GATE-CS-2001考试中的第8道问题,需要对给定的算法进行分析和实现。该问题主要涉及到图论中的最小生成树和动态规划算法。
给定一个连通加权无向图$G=(V,E)$和它的一棵生成树$T=(V',E')$,对于一个权重为$w$的边$e\in E\setminus E'$,我们可以在$T$中删除一条比这条边权重大的边,然后将该边加入$T$中,得到新的生成树$T'=(V',E'\cup{e'}\setminus{e''})$,其中$e''$是$T'\cap {e}$中权重最大的边。现在,我们需要设计一个算法,对于所有满足$w(e)>w(e'')$的边$e\in E\setminus E'$,找到权重最小的$e'$并输出。
这道问题可以用下面的动态规划算法解决:
接下来,我们来证明这个算法的正确性。
首先,令$T'_i=(V',E'\cup{e_1,\cdots,e_i}\setminus{e''_1,\cdots,e''_i})$,其中$e''_i$是$T'_i\cap {e_1,\cdots,e_i}$中权重最大的边。那么,由定义可知,$S_i$就是$T'_i$中所有边权最小的边权值。
然后,我们通过归纳证明来证明算法的正确性:
当$i=1$时,我们有$S_1=w(e_1)$。因为$w(e_1)>w(e''_1)$,所以$e_1$可以替换$e''_1$得到一颗比$T$更小的生成树,因此$S_1$是正确的。
假设当$i<k$时,$S_i$是正确的。我们需要证明$S_k$也是正确的。即证明,$S_k$可以由$S_{k-1}$通过一次替换得到,并且$w(e_k)=S_k$。
首先,由假设可知,$S_{k-1}$可以由$T'_{k-1}$中满足条件的边生成,而$T'k$可以由$T'{k-1}$替换其中一条边生成。因此,$S_k$可以由$T'_k$中满足条件的边生成,即$S_k\le w(e_k)$。
然后,我们需要证明$S_k\ge w(e_k)$。假设存在一颗树$T_0$,它满足:
那么,由假设可知,$S_{i}=w(T_{i-1}+{e_i})$。因为$T_0$是由$V'$和来自$E\setminus E'$中至少一条满足条件的边生成的,所以我们可以得到$T_0$中至少有一条边$e_j$满足$w(e_j)>w(e''_j)$。
然后,我们将$T_0$中权重最大的边删除,加入$e_i$,得到新的树$T_1$。这里需要注意,由于$T_0$中存在一条边满足$w(e_j)>w(e''_j)$,因此$e''_j$不可能是$e_i$中的边。因此,$T_1$是由$V'$和至少一条来自$E\setminus E'$中满足条件的边生成的。
由于$e_i$是$E\setminus E'$中权重最小的边,因此$w(e_i)\le w(e_j)$。因此,我们可以用$e_j$替换$e_i$,得到一颗树$T_2$,满足$T_2$是由$V'$和至少一条来自$E\setminus E'$中满足条件的边生成的,其边权之和小于等于$w(e_1)+\cdots+w(e_i)$。因此,$S_{i}=w(T_{i-1}+{e_i})\ge w(T_2)\ge S_{i-1}$。
综上,我们得到$S_k=S_{k-1}\cup{e_k}\setminus{e''k}$。因此,$S_k$可以由$S{k-1}$通过一次替换得到,并且$S_k\le w(e_k)$。由于归纳假设,$S_{k-1}$是正确的,因此$S_k$也是正确的。
综上,我们证明了该算法的正确性。下面给出该算法的实现代码:
# S1: 构造 T'
T_prime = {}
for e in E - E_prime:
e_max = max([e_ for e_ in T+{e} if e_ != e], key=lambda e: e.weight)
if e.weight > e_max.weight:
T_prime[e] = e_max
# S2: 排序所有符合条件的边
e_list = sorted([e for e in E - E_prime if e.weight > T_prime[e].weight], key=lambda e: e.weight)
# S3: Kruskal 算法求解 S_k
S_k = set(T_prime.values())
for e in e_list:
S_k.add(e)
S_k.discard(max([e_ for e_ in S_k if e_ != e], key=lambda e_: e_.weight))