题目描述
小明是蓝桥王国的王子,今天是他登基之日。
在即将成为国王之前,老国王给他出了道题,他想要考验小明是否有能力管理国家。
题目的内容如下:
蓝桥王国一共有N个建筑和M 条单向道路,每条道路都连接着两个建筑,每个建筑都有自己编号,分别为1~ N。(其中皇宫的编号为1)
国王想让小明回答从皇宫到每个建筑的最短路径是多少,但紧张的小明此时已经无法思考,请你编写程序帮助小明回答国王的考核。
输入描述
输入第一行包含三个正整数N , M。
第2到M+1行每行包含三个正整数 u, v, w,表示u→u之间存在一条距离为w的路。
1<N ≤3×10^5,1<m ≤10^6,1 ≤ui, vi ≤N ,0<w;≤10^9。
输出描述
输出仅一行,共N个数,分别表示从皇宫到编号为1~N建筑的最短距离,两两之间用空格隔开。(如果无法到达则输出―1)
输入输出样例
输入
输出
运行限制
主要思路:(个人理解)
-
输入:首先,从标准输入中获取两个整数
n
和m
,分别表示节点的数量和边的数量。 -
构建图:创建一个空的列表
distance
,其中第i
个元素是一个列表,用于存储节点i
的邻接节点以及对应的边权重。 -
读取边信息:通过循环读取
m
条边的信息,将每条边的起点、终点和权重添加到distance
中。 -
初始化距离和堆:创建一个列表
dp
,用于存储从起点到每个节点的最短距离,初始时将每个节点的距离设置为无穷大。同时,创建一个空堆q
,用于存储待处理的节点和它们的当前最短距离。 -
将起点加入堆中:将起点 1 加入堆中,初始距离为 0,并将起点的最短距离设置为 0。
-
实现 Dijkstra 算法:定义函数
dijkstra()
,在函数中使用堆和循环实现 Dijkstra 算法。在每次循环中,取出堆中当前最小距离的节点,并更新其邻接节点的最短距离。 -
输出结果:输出起点到自身的最短距离为 0,然后遍历从起点到其他节点的最短距离,如果某个节点不可达,则输出 -1。
总体来说,实现 Dijkstra 算法用于解决最短路径问题。算法的核心思想是通过贪心策略,逐步更新到达每个节点的最短距离,从而得到最终的最短路径。
关键代码:
import os
import sys
# 实现 Dijkstra 算法
import heapq
n, m = map(int, input().split())# 节点数量和边数量
distance = [[] for _ in range(n + 1)]
for _ in range(m):
u, v, w = map(int, input().split())
distance[u].append((v, w))
dp = [sys.maxsize] * (n + 1)
# 创建列表存储从起点到每个节点的最短距离。初始时,将每个节点的距离设置为无穷大
q = []# 空堆
heapq.heappush(q, (0, 1))# 起点 1 加入堆中,初始距离为 0
dp[1] = 0
def dijkstra():
visit = [0] * (n + 1)
while q:
v = heapq.heappop(q)[1]
if visit[v] == 1:
continue
visit[v] = 1
for a, b in distance[v]:
if visit[a] == 1:
continue
dp[a] = min(dp[a], dp[v] + b)
heapq.heappush(q, (dp[a], a))
dijkstra()# 调用算法
print(0, end=" ")
for i in range(2, n + 1):
# 输出从起点到其他节点的最短距离,如果某个节点不可达,则输出 -1
if dp[i] == sys.maxsize:
print(-1, end=" ")
else:
print(dp[i], end=" ")
在心里种花,人生才不会荒芜!!