📜  门| GATE-CS-2015(套装3)|第 40 题(1)

📅  最后修改于: 2023-12-03 14:58:30.450000             🧑  作者: Mango

门| GATE-CS-2015(套装3)|第 40 题

这是一道关于有向图的算法题目。

题目描述

给定一个有向图,找到从顶点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]]}")

注意,本题对字典序的要求比较高,因此在使用堆进行优化时,必须先比较成本,若成本相同,则比较距离。