[bzoj3245]最快路线
将每一个点拆成500个点,表示分别表示以某个速度到这里时的最短路,然后跑最短路即可,注意距离是double类型
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 205 4 struct ji{ 5 int nex,to,len,v; 6 }edge[N*N]; 7 struct ji2{ 8 int k,v; 9 }from[N][505]; 10 queue<ji2>q; 11 int E,n,m,k,x,y,v,z,head[N],ans[N],vis[N][505]; 12 double d[N][505]; 13 void add(int x,int y,int z,int v){ 14 edge[E].nex=head[x]; 15 edge[E].to=y; 16 edge[E].len=z; 17 edge[E].v=v; 18 head[x]=E++; 19 } 20 void spfa(){ 21 for(int i=1;i<=n;i++) 22 for(int j=1;j<=500;j++)d[i][j]=0x3f3f3f3f; 23 d[0][70]=0; 24 q.push(ji2{0,70}); 25 while (!q.empty()){ 26 ji2 k=q.front(); 27 q.pop(); 28 vis[k.k][k.v]=0; 29 for(int i=head[k.k];i!=-1;i=edge[i].nex){ 30 int v=edge[i].to,flag=0; 31 if (!edge[i].v){ 32 flag=1; 33 edge[i].v=k.v; 34 } 35 double x=1.0*edge[i].len/edge[i].v; 36 if (d[k.k][k.v]+x<d[v][edge[i].v]){ 37 from[v][edge[i].v]=k; 38 d[v][edge[i].v]=d[k.k][k.v]+x; 39 if (!vis[v][edge[i].v]){ 40 vis[v][edge[i].v]=1; 41 q.push(ji2{v,edge[i].v}); 42 } 43 } 44 if (flag){ 45 k.v=edge[i].v; 46 edge[i].v=0; 47 } 48 } 49 } 50 } 51 int main(){ 52 scanf("%d%d%d",&n,&m,&k); 53 memset(head,-1,sizeof(head)); 54 for(int i=1;i<=m;i++){ 55 scanf("%d%d%d%d",&x,&y,&v,&z); 56 add(x,y,z,v); 57 } 58 spfa(); 59 double s=d[k][1]; 60 for(int i=2;i<=500;i++)s=min(s,d[k][i]); 61 for(int i=1;i<=500;i++) 62 if (d[k][i]==s){ 63 ans[++ans[0]]=k; 64 ji2 t=from[k][i]; 65 while (t.k){ 66 ans[++ans[0]]=t.k; 67 t=from[t.k][t.v]; 68 } 69 } 70 printf("0"); 71 for(int i=ans[0];i;i--)printf(" %d",ans[i]); 72 }