📅  最后修改于: 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}')