对于这种有限制的最短路题,我们可以采用打表的思路,记录dis[i][j]是从源点到i点速度为j的最短时间,这就是分层图,将情况分类讨论
这种思路还可以处理这样的问题:我们可以最多让k条边的权值为0,求最短路,那么dis[i][j]就是记录从源点到i点用了j次使权值为0的最小边权和。
from queue import PriorityQueue
n,m,d=map(int ,input().split())
class node:
def __init__(self,v,ne,l,t,p):
self.v=v
self.l=l
self.t=t
self.ne=ne
self.p=p
line=[0]
cnt=0
h=[0 for i in range(200)]
for i in range(m):
a,b,v,l=map(int ,input().split())
if v==0:
cnt+=1
line.append(node(b,h[a],l,-1,-1))
h[a]=cnt
else :
cnt+=1
line.append(node(b,h[a],l,l/v,v))
h[a]=cnt
inf=float("inf")
dis=[[inf for i in range(510)]for i in range(200)]
class node2:
def __init__(self,u=inf,v=inf):
self.v=v
self.u=u
pre=[[node2() for i in range(510)]for i in range(200)]
vis=[[False for i in range(510)]for i in range(200)]
class node1:
def __init__(self,u,t,v):
self.t=t
self.u=u
self.v=v
def __lt__(self, other):
return self.t<other.t
def dj():
q=PriorityQueue()
dis[0][70]=0
q.put(node1(0,0,70))
while (q.qsize()):
mm=q.get()
ind=h[mm.u]
uu=mm.u
tt=mm.t
while (ind!=0):
vv=line[ind].v
if (line[ind].t==-1):
t=line[ind].l/mm.v
if (dis[vv][mm.v]>t+tt):
dis[vv][mm.v]=t+tt
q.put(node1(vv,t+tt,mm.v))
pre[vv][mm.v]=node2(uu,mm.v)
else:
if (dis[vv][line[ind].p]>line[ind].t+mm.t):
dis[vv][line[ind].p] = line[ind].t + mm.t
q.put(node1(vv,line[ind].t + mm.t,line[ind].p))
pre[vv][line[ind].p] = node2(uu,mm.v)
ind=line[ind].ne
dj()
minx=inf
ans=0
for i in range(510):
if (dis[d][i]<minx):
minx=dis[d][i]
ans=i
aa=[]
def dfs(x,v):
aa.append(x)
if (x==0):
return
x1=pre[x][v].u
v1=pre[x][v].v
dfs(x1,v1)
dfs(d,ans)
while (aa):
ans=aa.pop()
if ans!=d:print(ans,end=" ")
else: print(ans)