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
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 }
埋骨何须桑梓地,人生无处不青山