ALGO-5 最短路
给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。
数据规模与约定
对于10%的数据,n = 2,m = 2。
对于30%的数据,n <= 5,m <= 10。
对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点。
【输入形式】
第一行两个整数n, m。
接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。
【输出形式】
共n-1行,第i行表示1号点到i+1号点的最短路。
【样例输入】
3 3
1 2 -1
2 3 -1
3 1 2
【样例输出】
-1
-2
代码部分
先用floyd算法写的,10个样例超时了7个😓,应该是时间复杂度太高了(O(n^3)),代码如下:
s=input().split()
n=int(s[0])
m=int(s[1])
mp=[[float('inf')]*(n+1) for i in range(n+1)]
for i in range(m):
k=input().split()
mp[int(k[0])][int(k[1])]=int(k[2])
for k in range(n+1):
for i in range(n+1):
for j in range(n+1):
if mp[i][k]+mp[k][j]<mp[i][j]:
mp[i][j]=mp[i][k]+mp[k][j]
for i in range(1,n):
print(mp[1][i+1])
后改用spfa算法,通过了9个样例,只超时了1个
from queue import Queue
class node:
def __init__(self):
self.s=0 #边指向的节点
self.side=0 #边权
def spfa(s):
v=Queue()
vis[s]=1
v.put(s)
dis[s]=0
while(v.qsize()>0):
q=v.get(0) #每次取队首元素,去松弛与它相连的点
vis[q]=0
for i in range(len(mp[q])): #遍历队首元素的邻接表
if dis[mp[q][i].s]>dis[q]+mp[q][i].side:
dis[mp[q][i].s]=dis[q]+mp[q][i].side
if vis[mp[q][i].s]==1:
continue
v.put(mp[q][i].s)
x=input().split()
n=int(x[0])
m=int(x[1])
vis=[0]*(n+1)
dis=[float('inf')]*(n+1)
mp=[[]for i in range(n+1)]
for i in range(m):
h=node()
y=input().split()
h.s=int(y[1])
h.side=int(y[2])
mp[int(y[0])].append(h)
spfa(1)
for i in range(2,n+1):
print(dis[i])