📅  最后修改于: 2023-12-03 15:12:47.587000             🧑  作者: Mango
本题目来源于门爷的算法竞赛课程第30题。在这道题目中,我们需要给定n个点m条边的一个图,求从1到n的最短路上最大的边的权值是多少。
为了解决这道题目,我们可以考虑使用二分答案来解决。假设当前的mid值是$mid=\frac{L+R}{2}$,那么我们就需要判断是否有从1到n的最短路的长度大于等于mid,如果存在的话,那么我们就可以把mid缩小,反之,我们就可以把mid扩大。重复上述过程,直到L=R为止。
现在我们需要考虑怎么求从1到n的最短路的长度是多少。我们可以使用dijstra算法来解决这个问题,并且我们需要把权值大于mid的所有边都视为无效边,这样可以保证求出来的最短路长度一定是小于等于mid的。
import heapq
N = 500010
M = 2000010
INF = int(1e9)
n, m = map(int, input().split())
head = [-1] * N
edge = [0] * M
nxt = [-1] * M
dist = [INF] * N
cnt = 0
def add_edge(u, v, w):
global cnt
edge[cnt] = v
nxt[cnt] = head[u]
head[u] = cnt
cnt += 1
for i in range(m):
u, v, w = map(int, input().split())
add_edge(u, v, w)
add_edge(v, u, w)
def dijkstra(mid):
global dist
q = [(0, 1)]
visited = [False] * N
dist[1] = 0
while q:
u = heapq.heappop(q)[1]
if visited[u]:
continue
visited[u] = True
i = head[u]
while i != -1:
v = edge[i]
if dist[v] > dist[u] + (1 if i & 1 else mid):
dist[v] = dist[u] + (1 if i & 1 else mid)
heapq.heappush(q, (dist[v], v))
i = nxt[i]
def check(mid):
global dist
dist = [INF] * N
dijkstra(mid)
return dist[n] <= mid
l = 0
r = INF
while l < r:
mid = (l + r + 1) // 2
if check(mid):
l = mid
else:
r = mid - 1
print(l)
以上是本题的代码实现,代码使用Python语言编写,采用了堆优化的Dijkstra算法来求从1到n的最短路,同时使用二分答案的方法来解决本题。
本题比较经典,考察了算法竞赛中比较常见的二分答案和堆优化的Dijkstra算法的应用。除此之外,本题还考察了如何对图中的边进行标记(即将权值大于mid的边都视为无效边)。这些都是算法竞赛中非常有用的知识点,希望本篇文章对大家有所帮助。