首页 > 试题广场 >

小红送外卖

[编程题]小红送外卖
  • 热度指数:1175 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\hspace{15pt}学园城共有 n 个结点和 m 条双向道路,其中 1 号结点为 美食街,其余结点均为学校。保证整张图连通。

\hspace{15pt}小红的送餐流程如下:
\hspace{23pt}\bullet\, 从美食街出发前往某所学校送餐;
\hspace{23pt}\bullet\, 抵达后立即骑车返回美食街;
\hspace{15pt}上述流程重复 q 次,第 i 次需前往学校 a_i。请你计算,小红完成全部订单所需骑行距离的最小值。

输入描述:
\hspace{15pt}第一行输入三个整数 n,m,q\ \left(1 \leqq n,m,q \leqq 10^5\right) —— 结点数、道路数和送餐次数。 
\hspace{15pt}接下来 m 行,第 i 行输入三个整数 u_i,v_i,w_i\ \left(1 \leqq u_i,v_i \leqq n;\ u_i \neq v_i;\ 1 \leqq w_i \leqq 10^4\right),表示一条连接 u_iv_i 的双向道路,其长度为 w_i
\hspace{15pt}最后一行输入 q 个整数 a_1,a_2,\dots,a_q\ \left(2 \leqq a_i \leqq n\right),其中 a_i 表示第 i 次送餐的目的学校。


输出描述:
\hspace{15pt}输出一个整数,代表完成全部订单最少需要骑行的总距离。
示例1

输入

3 2 2
1 2 1
1 3 2
2 3

输出

6

说明

小红先从美食街骑到2号学校,再返回美食街,骑行距离为1+1=2
小红先从美食街骑到3号学校,再返回美食街,骑行距离为2+2=4
因此总共的骑行距离为2+4=6
import heapq


def dijkstra(n, adj, start):
    dist = [float("inf")] * (n + 1)  # 初始化距离数组,所有距离设为无穷大
    dist[start] = 0  # 起点到自身的距离为0
    heap = [(0, start)]  # 最小堆,存储 (距离, 节点) 元组
    while heap:
        d, u = heapq.heappop(heap)  # 弹出当前距离起点最近的节点
        # if d > dist[u]:
        #     continue  # 如果弹出的距离大于已知最短距离,跳过
        for v, w in adj[u]:  # 遍历当前节点的所有邻接节点
            if dist[v] > dist[u] + w:  # 如果通过当前节点到达邻接节点的距离更短
                dist[v] = dist[u] + w  # 更新最短距离
                heapq.heappush(heap, (dist[v], v))  # 将新的距离和节点加入堆中
    return dist


n, m, q = map(int, input().split())  # 读取节点数n,边数m,目标学校数q
adj = [[] for _ in range(n + 1)]  # 初始化邻接表
for _ in range(m):
    u, v, w = map(int, input().split())  # 读取每条边的信息
    adj[u].append((v, w))  # 添加边 u -> v,权重为 w
    adj[v].append((u, w))  # 添加边 v -> u,权重为 w(无向图)
targets = list(map(int, input().split()))  # 读取目标学校列表
dist = dijkstra(n, adj, 1)  # 计算从节点1到所有节点的最短路径
total = sum(2 * dist[t] for t in targets)  # 计算所有目标学校的往返距离之和
print(total)  # 输出总骑行距离

发表于 2025-04-11 12:39:51 回复(0)