这道题可以理解为是一个分层图,也可以理解为是二维的SPFA
dis[i][j]表示到达i这个点速度为j的最短路
然后跑已经死了的SPFA就好了;
#include <bits/stdc++.h> #define inc(i,a,b) for(register int i=a;i<=b;i++) using namespace std; int head[200010],cnt; int inf=2e9+1; class littlestar{ public: int to; int nxt; int w; int speed; void add(int u,int v,int gg,int hh) { to=v; nxt=head[u]; w=gg; speed=hh; head[u]=cnt; } }star[200010]; int n,m,T; class node1{ public: int u,speed; }; double dis[301][501]; int vis[301][501]; node1 pre[301][501]; void SPFA() { queue<node1> qwq; qwq.push((node1){0,70}); inc(i,0,n) inc(j,0,500) dis[i][j]=inf,pre[i][j].u=-1,pre[i][j].speed=-1; dis[0][70]=0; while(qwq.size()){ node1 tmp=qwq.front(); qwq.pop(); vis[tmp.u][tmp.speed]=0; for(int i=head[tmp.u];i;i=star[i].nxt){ int v=star[i].to; int now=star[i].speed; if(!now) now=tmp.speed; if(dis[tmp.u][tmp.speed]+(double)star[i].w/now<dis[v][now]){ dis[v][now]=dis[tmp.u][tmp.speed]+(double)star[i].w/now; pre[v][now].u=tmp.u; pre[v][now].speed=tmp.speed; if(!vis[v][now]){ vis[v][now]=1; qwq.push((node1){v,now}); } } } } } int ans[3000]; int main() { cin>>n>>m>>T; inc(i,1,m){ int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d); star[++cnt].add(a,b,d,c); } SPFA(); double minn=999999999.9,id=0; inc(i,0,500){ if(minn>dis[T][i]){ minn=dis[T][i];id=i; } } int now=T,now2=id,cnt=0; while(now!=-1){ ans[++cnt]=now; int tmp=now2; now2=pre[now][now2].speed; now=pre[now][tmp].u; } for(int i=cnt;i>=1;i--){ cout<<ans[i]<<" "; } } /* 6 15 1 0 1 25 68 0 2 30 50 0 5 0 101 1 2 70 77 1 3 35 42 2 0 0 22 2 1 40 86 2 3 0 23 2 4 45 40 3 1 64 14 3 5 0 23 4 1 95 8 5 1 0 84 5 2 90 64 5 3 36 40 */