【入门】最短距离及花费(python)

时间限制:C/ 1000MS,其他语言 2000MS
内存限制:C/ 128MB,其他语言 256MB
难度:中等
出题人:admin

描述

A国有n个城市,修建了m条道路(道路双向都可以走),每条道路的长度为d,走该路线要花费p元的过路费。

请问:如果要从编号为s的城市到编号为t的城市,最短距离是多少,如果按最短距离来走要花多少钱?

注意:如果有多条最短路,请输出花费最少的距离及花费。

输入描述

读入若干组数据,对于每组数据:

先输入n,m,城市的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a城市和b城市之间有一条边,且其长度为d,过路费花费为p。

最后一行是两个数 s,t,表示起点编号为s,终点编号为t。

当读入n和m为0时,表示输入结束。
(1<n≤1000, 0<m<100000, s != t)

输出描述

对于每组输入,输出一行有两个数, 表示最短距离及其花费。

用例输入 1 
3 2
1 2 5 6
2 3 4 5
1 3
0 0
用例输出 1 
9 11

code:

import sys
import heapq

def dijkstra(n, graph, s, t):
    # Initialize distance and cost arrays
    INF = float('inf')
    dist = [INF] * (n + 1)
    cost = [INF] * (n + 1)
    dist[s] = 0
    cost[s] = 0
    pq = []
    heapq.heappush(pq, (0, s))
    
    while pq:
        current_dist, u = heapq.heappop(pq)
        if u == t:
            return dist[u], cost[u]
        if current_dist > dist[u]:
            continue
        for neighbor, distance, road_cost in graph[u]:
            new_dist = current_dist + distance
            new_cost = cost[u] + road_cost
            if new_dist < dist[neighbor] or (new_dist == dist[neighbor] and new_cost < cost[neighbor]):
                dist[neighbor] = new_dist
                cost[neighbor] = new_cost
                heapq.heappush(pq, (new_dist, neighbor))
    return "unreachable", "unreachable"

def main():
    input = sys.stdin.read().strip().split('\n')
    idx = 0
    
    while True:
        line = input[idx].strip().split()
        n = int(line[0])
        m = int(line[1])
        
        if n == 0 and m == 0:
            break
        graph = [[] for _ in range(n + 1)]
        
        for _ in range(m):
            idx += 1
            a, b, d, p = map(int, input[idx].strip().split())
            graph[a].append((b, d, p))
            graph[b].append((a, d, p))
        
        s, t = map(int, input[idx + 1].strip().split())
        idx += 2
        shortest_distance, minimum_cost = dijkstra(n, graph, s, t)
        print(shortest_distance, minimum_cost)

if __name__ == "__main__":
    main()

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值