📜  门| GATE CS 2020 |问题 28(1)

📅  最后修改于: 2023-12-03 15:28:38.613000             🧑  作者: Mango

门 | GATE CS 2020 | 问题 28

本题为GATE CS 2020的问题28,考察了图的最小生成树算法。问题描述如下:

给定一个权重为正的无向连通图G=(V,E),其中V是节点集合,E是边集合,边权重为w。我们定义一个简单路径上的危险值为该路径上的最大边权重。将一个图G的所有简单路径上的危险值的最小值定义为该图的安全值,即:

saf(G) = min (max (w(e)): e为G的某条简单路径)

请编写程序,在O(m log n)时间内,计算一个无向连通图的安全值。

解题思路

对于一个无向图,很容易想到使用Kruskal算法或Prim算法求解最小生成树。所以我们先求出原图G的最小生成树T,之后我们需要在T中找出一条最长的边作为安全值的候选项。

我们可以采用如下方法:

  • 对于T中的每个节点v,以v为起点计算在T中的深度,记为d(v)。
  • 对于最小生成树T中的任意两个节点u和v,假定u在v的子树中,那么它们之间的边(e)权重必定不小于v的父节点的深度,即:w(e)>=d(parent(v))。因为假设u在v的子树中,那么v已经是最大深度的节点,所以u到v的路径上的边必然都大于等于该路径上的最大边权重(d(parent(v))),所以取d(parent(v))作为这条路径的安全值候选项。
  • 我们可以考虑对于T中的每个节点v,将其作为DFS树的根节点,求出以v为根节点的子树中的最大边权重maxv,再取这些maxv中的最小值minmax作为ans。
代码实现

按照上述思路,我们可以写出如下代码:(注意:以下代码仅为伪代码,仅供参考)

# Kruskal算法求最小生成树
T = Kruskal(G)

# 初始化ans为无穷大
ans = INF

for v in T:
    # 求以v为根节点的子树中的最大边权重
    maxw = dfs(T, v, -INF)
    # 更新ans
    ans = min(ans, maxw)

# 输出ans
print(ans)

# 求以v为根节点的子树中的最大边权重
def dfs(T, v, maxw):
    for u in T.get_adjacent_nodes(v):
        maxw = max(maxw, T.get_weight(u, v))
        dfs(T, u, maxw)
    return maxw

以上是本题的解题思路和代码实现,可以通过Kruskal算法和DFS求解。