蓝桥王国python

题目描述

小明是蓝桥王国的王子,今天是他登基之日。

在即将成为国王之前,老国王给他出了道题,他想要考验小明是否有能力管理国家。

题目的内容如下:

蓝桥王国一共有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)

输入输出样例

输入

输出

运行限制

主要思路:(个人理解)

  1. 输入:首先,从标准输入中获取两个整数 nm,分别表示节点的数量和边的数量。

  2. 构建图:创建一个空的列表 distance,其中第 i 个元素是一个列表,用于存储节点 i 的邻接节点以及对应的边权重。

  3. 读取边信息:通过循环读取 m 条边的信息,将每条边的起点、终点和权重添加到 distance 中。

  4. 初始化距离和堆:创建一个列表 dp,用于存储从起点到每个节点的最短距离,初始时将每个节点的距离设置为无穷大。同时,创建一个空堆 q,用于存储待处理的节点和它们的当前最短距离。

  5. 将起点加入堆中:将起点 1 加入堆中,初始距离为 0,并将起点的最短距离设置为 0。

  6. 实现 Dijkstra 算法:定义函数 dijkstra(),在函数中使用堆和循环实现 Dijkstra 算法。在每次循环中,取出堆中当前最小距离的节点,并更新其邻接节点的最短距离。

  7. 输出结果:输出起点到自身的最短距离为 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=" ")

在心里种花,人生才不会荒芜!!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值