题目大意
有一个无向图,图中有一些边,这些边有两个信息,距离和花费。现在给出起点和终点,问从起点到终点最短的距离的路径,如果有多条,输出其中花费最少的那条(保证答案唯一)
输入
每组包含一个测试用例,每个用例的第一行是四个正整数 N , M , S , D N, M, S, D N,M,S,D
- N N N表示点的数量( ≤ 500 \leq 500 ≤500), 点的编号从 0 0 0到 N − 1 N-1 N−1
- M M M表示边的数量
- S S S表示起点
- D D D表示终点
之后的 M M M行给出边的信息
点1 点2 距离 花费
输出
对每个样例,在一行内输出从起点到终点满足题意的最短路径,并输出最短路径的距离和花费
样例输入
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
样例输出
0 2 3 3 40
解析
用dijkstra算法即可得解,只是在判断距离时还要再加上对花费的判断
def solve():
INF = 0x7fffffff
n, m, s, d = map(int, input().split())
cost = [INF for i in range(n)]
vis = [False for i in range(n)]
edge = [[[-1, -1] for i in range(n)] for j in range(n)]
dis = [INF for i in range(n)]
path = [[] for i in range(n)]
for i in range(m):
a, b, D, c = map(int, input().split())
edge[a][b], edge[b][a] = [D, c], [D, c]
path[s] = [s]
vis[s] = True
dis[s], cost[s] = 0, 0
mark = s
while mark != -1:
indexOfEdge = [i for i in range(n) if edge[mark][i] != [-1, -1] and not vis[i]]
for i in indexOfEdge:
if dis[mark] + edge[mark][i][0] < dis[i]:
dis[i] = dis[mark] + edge[mark][i][0]
cost[i] = cost[mark] + edge[mark][i][1]
path[i] = path[mark]+[i]
elif dis[mark] + edge[mark][i][0] == dis[i]:
if cost[i] > cost[mark] + edge[mark][i][1]:
path[i] = path[mark]+[i]
cost[i] = cost[mark] + edge[mark][i][1]
tmp = [i for i in range(n) if dis[i] != INF and not vis[i]]
if len(tmp) == 0:
mark = -1
else:
mark = sorted(tmp, key=lambda x: dis[x])[0]
vis[mark] = True
print(*path[d], dis[d], cost[d])
if __name__ == "__main__":
solve()