📅  最后修改于: 2023-12-03 14:58:30.450000             🧑  作者: Mango
这是一道关于有向图的算法题目。
给定一个有向图,找到从顶点1到n的最短路径。每个边有两个权重,一个为时间,一个为经济成本。对于任何从1到n的路径,通过时间限制选择一个路径,使经济成本最小化。如果存在多个路径控制成本,则选择最短路径。如果存在多个路径具有相同的时间和成本,则选择其中字典序最小的路径。
输入文件的第一行包含两个整数n和m,表示顶点数和边数。下面的m行包含有向边(u,v)和u到v的成本(c1)和时间(c2)。
打印从1到n的最短路径。对于每个顶点,输出每个顶点所在的路径的成本和时间。输出格式如下所示:
v: distance=distanceValue cost=costValue time=timeValue path=pathList
本题可以通过Dijkstra算法来求解最短路径。不同于普通的Dijkstra算法,我们需要考虑到成本的影响。因此,需要引入一个额外的维度,即成本维度。同时,为了满足字典序的要求,我们需要在更新距离和成本的同时记录路径列表。在记录路径时,需要记录到达每个节点时所花费的成本和时间,以及上一个节点。
下面是Python实现的代码,其中包含了对Dijkstra算法的若干个优化,例如使用堆进行优化,以及使用数组进行距离和成本的更新。
from heapq import heappop, heappush
def dijkstra(graph):
n = len(graph)
visited = [False] * n
distance = [float("inf")] * n
cost = [float("inf")] * n
path = [[] for _ in range(n)]
heap = [(0, 0, 0, 1)]
distance[0] = 0
cost[0] = 0
while heap:
_, c, t, node = heappop(heap)
if visited[node-1]:
continue
visited[node-1] = True
for neighbor, (w1, w2) in graph[node-1].items():
if visited[neighbor-1]:
continue
newDistance = distance[node-1] + w1
newCost = cost[node-1] + w2
if newCost < cost[neighbor-1] or (newCost == cost[neighbor-1] and newDistance < distance[neighbor-1]):
distance[neighbor-1] = newDistance
cost[neighbor-1] = newCost
path[neighbor-1] = path[node-1] + [(newCost, newDistance, node)]
heappush(heap, (distance[neighbor-1]+cost[neighbor-1], newCost, newDistance, neighbor))
return path
# 输入
n, m = map(int, input().split())
graph = [{} for _ in range(n)]
for _ in range(m):
u, v, c1, c2 = map(int, input().strip().split())
graph[u-1][v] = (c1, c2)
# 计算并输出结果
path = dijkstra(graph)
for i in range(n):
if not path[i]:
print(f"{i+1}: NO PATH")
else:
print(f"{i+1}: distance={path[i][-1][1]} cost={path[i][-1][0]} time={path[i][-1][1]} path={[p[2] for p in path[i]]}")
注意,本题对字典序的要求比较高,因此在使用堆进行优化时,必须先比较成本,若成本相同,则比较距离。