classDijkstra:def__init__(self, n, edges, start, undirected=True):
self.n = n
self.start = start
self.edges = edges
self.undirected = undirected
self.dis =[float('inf')]* n
self.pre =[start]* n
self.dijkstra()defdijkstra(self):
mat =[[float('inf')]* self.n for _ inrange(self.n)]for i inrange(self.n):
mat[i][i]=0for i, j, w in self.edges:if i == self.start:
self.dis[j]= w
mat[i][j]= w
if self.undirected:
mat[j][i]= w
if j == self.start:
self.dis[i]= w
done =[self.start]
pending =[i for i inrange(self.n)if i != self.start]while pending:
relay = pending[0]for point in pending:if self.dis[point]< self.dis[relay]:
relay = point
done.append(relay)
pending.remove(relay)for point in pending:if self.dis[point]> self.dis[relay]+ mat[relay][point]:
self.dis[point]= self.dis[relay]+ mat[relay][point]
self.pre[point]= relay
def__call__(self, j):if self.start == j:return0,str(self.start)
p =[j]while self.pre[p[-1]]!= self.start:
p.append(self.pre[p[-1]])
p.append(self.start)return self.dis[j],'->'.join(str(c)for c inreversed(p))if self.dis[j]!=float('inf')else''classFloyd:def__init__(self, n, edges, undirected=True):
self.n = n
self.mat =[[float('inf')]* n for _ inrange(n)]for i inrange(n):
self.mat[i][i]=0for i, j, w in edges:
self.mat[i][j]= w
if undirected:
self.mat[j][i]= w
self.pre =[[r]* n for r inrange(n)]
self.floyd()deffloyd(self):for k inrange(self.n):for i inrange(self.n):for j inrange(self.n):if self.mat[i][j]> self.mat[i][k]+ self.mat[k][j]:
self.mat[i][j]= self.mat[i][k]+ self.mat[k][j]
self.pre[i][j]= k
def__call__(self, i, j):if i == j:return0,str(i)
p =[i, j]
k =0while k <len(p)-1:if self.pre[p[k]][p[k +1]]== p[k]:
k +=1else:
p.insert(k +1, self.pre[p[k]][p[k +1]])return self.mat[i][j],'->'.join(str(c)for c in p)if self.mat[i][j]!=float('inf')else''