BZOJ3245 最快路线

Description

精 明的小R每每开车出行总是喜欢走最快路线,而不是最短路线.很明显,每条道路的限速是小R需要考虑的关键问题.不过有一些限速标志丢失了,于是小R将不知 道能开多快.不过有一个合理的方法是进入这段道路时不改变速度行驶.你的任务就是计算从小R家(0号路口)到D号路口的最快路线.
现在你得到了这个城市的地图,这个地图上的路都是单向的,而且对于两个路口A和B,最多只有一条道路从A到B.并且假设可以瞬间完成路口的转弯和加速.

Input

第一行是三个整数N,M,D(路口数目,道路数目,和目的地). 路口由0...N-1标号
接下来M行,每行描述一条道路:有四个整数A,B,V,L,(起始路口,到达路口,限速,长度) 如果V=0说明这段路的限速标志丢失.
开始时你位于0号路口,速度为70.

Output

 
仅仅一行,按顺序输出从0到D经过的城市.保证最快路线只有一条.

Sample Input

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

Sample Output

0 5 2 3 1

HINT

【数据范围】

30% N<=20

100% 2<=N<=150;0<=V<=500;1<=L<=500

 
终于破案了。。。。。懂了思路,写了4遍答案都不对。。。
 
思路:dis[i][j]  表示达到i点速度为j的最短时间。然后spfa。由于要输出路径。那么可以记录前一个点,前一个速度,然后递归输出。
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int inf=0x3f3f3f3f;
  4 int n,m,ed,tol,prepos[155][510],prev[155][510],head[155];
  5 bool inq[155][510];
  6 double dis[155][510];
  7 
  8 struct Edge{
  9     int to,v,l,next;
 10 }edge[155*155];
 11 
 12 struct node{
 13     int pos,v;
 14     node(){}
 15     node(int _pos,int _v) {
 16         pos=_pos;
 17         v=_v;
 18     }
 19 };
 20 
 21 void spfa() {
 22     queue<node> q;
 23     dis[0][70]=0;
 24     inq[0][70]=true;
 25     q.push(node(0,70));
 26     while(!q.empty()) {
 27         node f=q.front();
 28         q.pop();
 29         int x=f.pos,vx=f.v;
 30         inq[x][vx]=false;
 31         for(int i=head[x];i!=-1;i=edge[i].next) {
 32             int y=edge[i].to,vy=edge[i].v,l=edge[i].l;
 33             if(vy&&(dis[y][vy]>dis[x][vx]+(double)l/vy)) {
 34                 dis[y][vy]=dis[x][vx]+(double)l/vy;
 35                 prepos[y][vy]=x;
 36                 prev[y][vy]=vx;
 37                 if(!inq[y][vy]) {
 38                     inq[y][vy]=true;
 39                     q.push(node(y,vy));
 40                 }
 41             }
 42             if(!vy&&(dis[y][vx]>dis[x][vx]+(double)l/vx)) {
 43                 dis[y][vx]=dis[x][vx]+(double)l/vx;
 44                 prepos[y][vx]=x;
 45                 prev[y][vx]=vx;
 46                 if(!inq[y][vx]) {
 47                     inq[y][vx]=true;
 48                     q.push(node(y,vx));
 49                 }
 50             }
 51         }
 52     }
 53 }
 54 
 55 void init() {
 56     tol=0;
 57     for(int i=0;i<=n;i++) {
 58         head[i]=-1;
 59         for(int j=0;j<=500;j++) {
 60             dis[i][j]=inf*1.0;
 61             inq[i][j]=false;
 62         }
 63     }
 64 }
 65 
 66 void addedge(int u,int v,int speed,int len) {
 67     edge[tol].to=v;
 68     edge[tol].v=speed;
 69     edge[tol].l=len;
 70     edge[tol].next=head[u];
 71     head[u]=tol++;
 72 }
 73 
 74 void print(int x,int y) {
 75     if(x!=0) print(prepos[x][y],prev[x][y]);
 76     printf("%d",x);
 77     if(x!=ed) printf(" ");
 78 }
 79 
 80 int main() {
 81     while(~scanf("%d%d%d",&n,&m,&ed)) {
 82         init();
 83         for(int i=1;i<=m;i++) {
 84             int u,v,speed,len;
 85             scanf("%d%d%d%d",&u,&v,&speed,&len);
 86             addedge(u,v,speed,len);
 87         }
 88         spfa();
 89         int vv;
 90         double minn=inf;//真坑啊啊啊!!!定义成int 就GG了
 91         for(int i=0;i<=500;i++) {
 92             if(dis[ed][i]<minn) {
 93                 vv=i;
 94                 minn=dis[ed][i];
 95             }
 96         }
 97         print(ed,vv);
 98         printf("\n");
 99     }
100 }

 

 
 
 
posted @ 2019-05-02 09:17  Frontierone  阅读(229)  评论(0编辑  收藏  举报