在有向加权图中,有效地找到穿过节点 X 的两个节点 A 和 B 之间的最短路径的成本

In a directed, weighted graph, efficiently find the cost of the shortest path between two nodes A and B that traverses through a node X

我是初学者,仍在掌握路径算法的概念。我们的教授给了我们这个问题,哪个解决方案将由在线评委评估:

我得到以下信息:

我需要找到从 A 到 X 到 B 的最短路径的成本。

我的代码运行如下:

  1. 获取输入。
  2. 生成图的邻接表。
  3. 获取 A、X 和 B。
  4. 获取A和X之间最短路径的成本ax
  5. 获取X和B之间最短路径的成本xb
  6. 从A到X到B的最短路径的成本axbax + xb

裁判判定本题超过1秒的时限。有没有办法改进它并使其更有效率?

def shortestPath(dist, i, j, k): # My first try in applying the Floyd-Warshall Algorithm

    for k in range(len(dist)):
        for i in range(len(dist)):
            for j in range(len(dist)):
                if dist[i][j] > dist[i][k] + dist[k][j]:
                    dist[i][j] = dist[i][k] + dist[k][j]

# Graph construction and algorithm application:
    .
    .
    .
    # generate adjacency list of the graph
    graph = [[math.inf for node_x in range(nodes)] for node_y in range(nodes)]
    next = [[None for node_x in range(nodes)] for node_y in range(nodes)]
    for node in range(nodes):
        graph[node][node] = 0

    for edge in range(edges):
        node_a, node_b, cost = input().split()
        node_a = int(node_a) - 1
        node_b = int(node_b) - 1
        cost = eval(cost)
        graph[node_a][node_b] = cost
        next[node_a][node_b] = node_b

    i, k, j = input().split()  # get source, traversed and destination node
    i = int(i) - 1
    j = int(j) - 1
    k = int(k) - 1
    shortestPath(graph, i, j, k)
    ikj = graph[i][j]

    if ikj == math.inf:  # path nonexistent if either ax or xb is infinite
        out.append("path nonexistent")
        continue
    else:
        out.append(ikj)

这是我的代码:

import heapq
import math


# tools start here

def dijkstra(G, S):
    pq = []
    costs = {v: math.inf for v in G}
    costs[S] = 0

    heapq.heappush(pq, (0, S))
    while pq:
        d_u, u = heapq.heappop(pq)
        for e in G[u]:
            v, w = e
            d_v = costs[v]
            if d_v > d_u + w:  # relaxation operation
                costs[v] = d_u + w
                heapq.heappush(pq, (d_u + w, v))
    return costs


# tools end here

t = int(input())  # get number of test cases
out = []  # initialize output array
for _ in range(t): # for each test case

    # get input
    nodes, edges = input().split()
    nodes = int(nodes)
    edges = int(edges)

    # generate adjacency list of the graph
    graph = {}
    for node in range(1, nodes + 1):
        graph[str(node)] = []

    for edge in range(edges):
        node_a, node_b, cost = input().split()
        cost = eval(cost)
        graph[node_a].append((node_b, cost,))

    a, x, b = input().split()  # get source, traversed and destination node

    ax = dijkstra(graph, a)[x]  # get shortest path cost from a to x
    xb = dijkstra(graph, x)[b]  # get shortest path cost from x to b

    axb = ax + xb  # add the path costs

    if axb == math.inf:  # path nonexistent if either ax or xb is infinite
        out.append("path nonexistent")
        continue
    else:
        out.append(axb)

[print(_) for _ in out]  # print output array

这是示例输入:

2
3 2
1 2 1
2 3 1
1 2 3
3 1
1 2 1
1 2 3

这是示例输出:

2
path nonexistent

我认为你的解决方案已经是最快的了。

如果您想从代码中获得更多运行时性能,我建议重新检查 A 和 X 之间的路径是否存在,然后是 X 和 B。

我还建议将您的 eval() 替换为 int(),因为考虑到您的问题的限制,假设检查它是否为 int 以外的任何东西会更慢。

最后,这很可能是一个在线判断,它接受打印输出的代码,因此在每个测试用例后立即输出答案。

希望对您有所帮助!