📜  门|门CS 2012 |第 42 题(1)

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

题目

题目链接:门|门CS 2012 第 42 题

题目描述

给你一个 $n$ 个点 $m$ 条边的图,其中边权有些为负。请你计算从 $1$ 号点到 $n$ 号点的最短路经过的边中最小的边权绝对值。 即从 $1$ 号点到 $n$ 号点的最短路为 $dis[n]$,输出 $\min_{(u,v)\in path} |w(u, v)|$,其中 $path$ 表示 $1$ 号点到 $n$ 号点的最短路径上的边集,$w(u, v)$ 表示 $u \to v$ 的边权。 如果最短路不存在则输出 $0$。

输入格式

第一行包含两个整数 $n,m$。

接下来 $m$ 行,每行包含三个整数 $u,v,w$,表示存在一条从 $u$ 到 $v$ 的边,边权为 $w$。

输出格式

输出最小的绝对值边权,精确到两位小数。

样例输入
4 4
1 2 0
2 3 -1
3 4 3
1 4 -4
样例输出
1.00
题解

这是经典的单源最短路问题,可以使用 Dijkstra 或 Bellman-Ford 算法解决,而此题要求求最小绝对值,所以需要使用 Bellman-Ford 算法。

使用 Bellman-Ford 算法求最短路时,需要对每一条边进行 $n-1$ 次松弛操作。我们可以在松弛操作时,同时记录边权绝对值最小的那条边,即可解决此题。

标准的 Bellman-Ford 算法时间复杂度为 $O(nm)$,可以通过滚动数组优化到 $O(m)$。

代码片段
n, m = map(int, input().split())

INF = 0x3f3f3f3f
dis = [INF] * (n + 1)

edges = []
for i in range(m):
    u, v, w = map(int, input().split())
    edges.append((u, v, w))

dis[1] = 0
abs_min_edge = INF

for i in range(n):
    abs_min_edge = INF  # 记录绝对值最小的边
    for j in range(m):
        u, v, w = edges[j]
        if dis[u] != INF and dis[u] + w < dis[v]:
            dis[v] = dis[u] + w
            abs_min_edge = min(abs_min_edge, abs(w))
    if abs_min_edge == 0:
        print(0.00)
        exit()

print(f'{abs_min_edge:.2f}')