朴素迪杰斯特拉算法(适用于稠密图): S:当前已经确定最短距离的点的集合
①初始化距离。dis[1]=0 其余正无穷
②for v :0~n:
不在S中的距离最近的点t
t放入s中
用t更新其他点的距离
#n为节点个数、g为邻接矩阵、dis为距离1号点的距离、st表示是否已经确定最短路径
#初始化
N=510 #节点总数,看题目
g=[[float('inf')]*N for _ in range(N)]
st=[False]*N#表示是否已经确定了最短路
dis=[float('inf')]*N#距离起点的距离
def djstl(n):
dis[1]=0
for i in range(n):
t=-1
for j in range(1,n+1):#找目前可以确定距离1号点最近的点
if not st[j] and (t==-1 or dis[t]>dis[j]):
t=j
st[t]=True #该点已经确定最短路了
for j in range(1,n+1):
dis[j]=min(dis[j],dis[t]+g[t][j])#更新其余点的最短路
return dis[n] if dis[n]!=float('inf') else -1
堆优化版的迪杰斯特拉算法(适用于稀疏图)
#graph为邻接表存储方式:
for i in range(m):
x,y,z=map(int,input().split())
if x in graph:
graph[x].append((y,z))
else:
graph[x]=[(y,z)]
def djsta(n):
qe=PQ()
qe.put((0,1))
distence[1]=0
while not qe.empty():
dis,t=qe.get()
if st[t]:continue
st[t]=True
if t not in graph:continue
for pa,pb in graph[t]:
if distence[pa]>distence[t]+pb:
distence[pa]=distence[t]+pb
qe.put((distence[t]+pb,pa))
return distence[n] if distence[n]!=float('inf') else -1
Bellman-Ford算法(有负权边时使用)(同时可以限制边的条数)
distence=[float('inf')]*N
graph=[]
for i in range(m):
x,y,z=map(int,input().split())
graph.append((x,y,z))
def bellman_ford(ks):
distence[1]=0
for i in range(ks):
backup=distence.copy()
for k,ver,dis in graph:
distence[ver]=min(distence[ver],backup[k]+dis)
if distence[n]==float('inf'):
print("impossible")
else:
print(distence[n])
SPFA算法:
def SPFA(n):
distence[1]=0
qe=[]
qe.append(1)
st[1]=True
while len(qe)!=0:
t=qe.pop(0)
st[t]=False
if t not in graph:continue
for ver,dis in graph[t]:
if distence[ver]>distence[t]+dis:
distence[ver]=distence[t]+dis
if not st[ver]:
qe.append(ver)
st[ver]=True
if distence[n]==float('inf'):
print("impossible")
else:
print(distence[n])
多源汇:
Floyd算法:
n,m,k=map(int,input().split())#删除自环
N=210
graph=[[float('inf')]*N for i in range(N)]
for p in range(N):
graph[p][p]=0
def Floyd(n):
for k in range(1,n+1):
for i in range(1,n+1):
for j in range(1,n+1):
graph[i][j]=min(graph[i][j],graph[i][k]+graph[k][j])
for i in range(m):
x,y,z=map(int,input().split())
graph[x][y]=min(graph[x][y],z)
Floyd(n)
for i in range(k):
x,y=map(int,input().split())
if graph[x][y]!=float('inf'):
print(graph[x][y])#重边选最小
else:
print("impossible")