蓝桥国王2

文章讲述了在蓝桥王国的登基考验中,王子小明需解决关于建筑间最短路径和kth短路的问题,通过Dijkstra算法和堆数据结构实现。主要介绍了如何构建图、使用堆计算最短路径,并提供关键代码段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

题目的内容如下:

蓝桥王国一共有N个建筑和M条单向道路,每条道路都连接着两个建筑,每个建筑都有自己编号,

分别为1~N。(其中皇宫的编号为1)从皇宫到每个建筑的最短路径是多少?

经过你的帮助,小明轻松的回答了该问题,但是国王的考验并不仅仅这么简单。很快国王又提出了

一个问题,他要小明回答从建筑S到建筑T的第K短路的长度为多少?

小明此时已经失去了思考能力,作为他的好朋友,请你再次帮帮他。

输入描述

输入第一行包含三个正整数N, M 。

第2到M+1行每行包含三个正整数u,v, w,表示u→ v之间存在一条距离为w的路。

第M+2行包含三个正整数S,T,K。

1 ≤s,T≤N≤10^3,1 ≤ m ≤10^5,1 ≤ui, vi ≤N,0≤wi≤ 10^3,保证S≠ T。

输出描述

输出占一行,包含一个整数,表示S→T的第K短路的长度,如果第K短路不存在,则输出-1。

输入输出样例

实例1

输入

输出

实例2

输入

输出

运行限制

  • 最大运行时间:1s
  • 最大运行内存:128M

主要思路 :(个人理解)

  1. 构建图:根据输入的道路信息,创建一个邻接表表示的图。图的节点是建筑,每个节点的邻居是与其相连的建筑以及对应的道路权重。

  2. 实现函数:该函数使用堆(heapq)来实现 Dijkstra 算法,以计算从起点到终点的前K短路径。堆中的元素是三元组 ,分别表示到达节点、路径花费、当前路径。

  3. 主函数调用:读取输入,包括建筑数量N、道路数量M、道路信息roads、起点S、终点T和目标路径序号K。然后调用 函数,得到结果并输出。

总体来说,代码采用了 Dijkstra 算法来计算最短路径,使用堆来维护当前可能的最短路径,并通过遍历邻居节点来不断更新堆中的路径信息。最终,通过检查找到的路径列表,返回第K短路径的长度或者 -1(如果第K短路径不存在)。

关键代码:

import os
import sys

import heapq
# 用于实现堆数据结构

def kth_shortest_path(N, M, roads, S, T, K):
    graph = [[] for _ in range(N + 1)]
    # 创建空列表表示建筑之间的图

    for u, v, w in roads:
        graph[u].append((v, w))
        # 将道路信息加入图中,表示从建筑u到建筑v存在一条边,边的权重为w

    def k_shortest_paths(start, end, k):
        # 计算从起点到终点的前K短路径
        heap = [(0, start, [])]
        visited = set()
        # 创建集合跟踪已访问的节点,防止重复访问

        paths = []
        # 创建空列表,存储找到的路径
        while heap:
            # 循环直到堆为空
            cost, node, path = heapq.heappop(heap)

            if node == end:
                # 当前节点是终点
                paths.append((cost, path))

            if len(paths) == k:
                # 如果已经找到k条路径结束循环
                return paths

            if node not in visited:
                # 没有被访问
                visited.add(node)# 将当前节点标记为已访问
                for neighbor, edge_cost in graph[node]:
                    # 遍历当前节点的邻节点和对应边权重
                    heapq.heappush(heap, (cost + edge_cost, neighbor, path + [(node, neighbor)]))

        return paths

    kth_paths = k_shortest_paths(S, T, K)

    return kth_paths[K - 1][0] if K <= len(kth_paths) else -1

if __name__ == "__main__":
    N, M = map(int, input().split())
    # 输入建筑数量N和道路数量M
    roads = [tuple(map(int, input().split())) for _ in range(M)]
    # 输入M条道路的具体信息。
    S, T, K = map(int, input().split())
    # 输入起点S、终点T和目标路径序号K

    result = kth_shortest_path(N, M, roads, S, T, K)
    print(result)

悟以往之不谏,知来者之可追!!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值