https://www.luogu.org/problem/show?pid=1266
我靠直接裂点;
就是d[i][j]表示在速度为j的时候到i最短时间;
相对的g[i][j][2]就记录方案;
这样大力裂点跑spfa就好了;
这样的话,原来的queue里面要存两个值;
一个是点,一个是速度;
但是我懒,仅仅存了点;
然后在spfa的时候枚举速度;
虽然满了一点,还是过了;
#include<bits/stdc++.h>
using namespace std;
struct cs{int to,l,v,nxt;}a[80000];
int head[200],ll;
double d[200][505];
bool in[200];
int g[200][505][2];
int n,m,E,x,y,l,v;
void init(int x,int y,int v,int l){
a[++ll].to=y;
a[ll].v=v;
a[ll].l=l;
a[ll].nxt=head[x];
head[x]=ll;
}
void out(int x,int y){
if(g[x][y][1])out(g[x][y][0],g[x][y][1]);
printf("%d ",x);
}
void spfa(int S){
for(int i=0;i<=n;i++)
for(int j=0;j<=500;j++)d[i][j]=1e9;
d[0][70]=0;
queue<int>Q;
Q.push(0);
while(!Q.empty()){
int x=Q.front();Q.pop();in[x]=0;
for(int i=1;i<=500;i++)
if(d[x][i]!=1e9)
for(int k=head[x];k;k=a[k].nxt){
int v;
if(a[k].v)v=a[k].v;else v=i;
double t=(double)a[k].l/v;
if(d[a[k].to][v]>d[x][i]+t){
d[a[k].to][v]=d[x][i]+t;
g[a[k].to][v][0]=x;
g[a[k].to][v][1]=i;
if(!in[a[k].to]){
in[a[k].to]=1;
Q.push(a[k].to);
}
}
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&E);
while(m--){
scanf("%d%d%d%d",&x,&y,&v,&l);
init(x,y,v,l);
}
spfa(0);
int mi=1;
for(int i=1;i<=500;i++)if(d[E][i]<d[E][mi])mi=i;
out(E,mi);
}