天梯地图(Dijkstra变形)
来源:互联网 发布:戏精 知乎 编辑:程序博客网 时间:2024/05/10 11:37
天梯地图
本题要求你实现一个天梯赛专属在线地图,队员输入自己学校所在地和赛场地点后,该地图应该推荐两条路线:一条是最快到达路线;一条是最短距离的路线。题目保证对任意的查询请求,地图上都至少存在一条可达路线。
输入格式:
输入在第一行给出两个正整数N
(2 ≤ N
≤ 500)和M
,分别为地图中所有标记地点的个数和连接地点的道路条数。随后M
行,每行按如下格式给出一条道路的信息:
V1 V2 one-way length time
其中V1
和V2
是道路的两个端点的编号(从0到N
-1);如果该道路是从V1
到V2
的单行线,则one-way
为1,否则为0;length
是道路的长度;time
是通过该路所需要的时间。最后给出一对起点和终点的编号。
输出格式:
首先按下列格式输出最快到达的时间T
和用节点编号表示的路线:
Time = T: 起点 => 节点1 => ... => 终点
然后在下一行按下列格式输出最短距离D
和用节点编号表示的路线:
Distance = D: 起点 => 节点1 => ... => 终点
如果最快到达路线不唯一,则输出几条最快路线中最短的那条,题目保证这条路线是唯一的。而如果最短距离的路线不唯一,则输出途径节点数最少的那条,题目保证这条路线是唯一的。
如果这两条路线是完全一样的,则按下列格式输出:
Time = T; Distance = D: 起点 => 节点1 => ... => 终点
输入样例1:
10 150 1 0 1 18 0 0 1 14 8 1 1 15 4 0 2 35 9 1 1 40 6 0 1 17 3 1 1 28 3 1 1 22 5 0 2 22 1 1 1 11 5 0 1 31 4 0 1 19 7 1 1 33 1 0 2 56 3 1 2 15 3
输出样例1:
Time = 6: 5 => 4 => 8 => 3Distance = 3: 5 => 1 => 3
输入样例2:
7 90 4 1 1 11 6 1 3 12 6 1 1 12 5 1 2 23 0 0 1 13 1 1 3 13 2 1 2 14 5 0 2 26 5 1 2 13 5
输出样例2:
Time = 3; Distance = 4: 3 => 2 => 5
关键在于如果最快到达路线不唯一,则输出几条最快路线中最短的那条,题目保证这条路线是唯一的。
而如果最短距离的路线不唯一,则输出途径节点数最少的那条,题目保证这条路线是唯一的。
根据这个,在Dijkstra算法中,更新点的d值时候,不仅仅要在d[u]>d[v]+G[v][u]时候更新,在等于的时候也有可能要更新,等于的时候要进行判断,然后看是否更新。
等于更新的条件容易出bug,在这被死循环了好久。
题目地址:https://www.patest.cn/contests/gplt/L3-007
代码:
#include <iostream>#include <cstdio>#include <cmath>#include <queue>#include <stack>#include <map>#include <algorithm>#include <vector>#include <string>#include <cstring>#include <sstream>#define INF 100000000using namespace std;int G[505][505]; //lengthint M[505][505]; //timeint n,m;int s,e;int path[1005];int t[1005];bool used[1005];int dis[505];int has[505];int ppath[505];int jiedian(int u){ int tmp=0; while(ppath[u]!=s) { tmp++; u=ppath[u]; } tmp++; return tmp;}void Dijkstra2(){ fill(has,has+n,false); fill(dis,dis+n,INF); memset(ppath,-1,sizeof(ppath)); dis[s]=0; while(1) { int v=-1; for(int u=0;u<n;u++) { if((v==-1 || dis[u]<dis[v]) && !has[u]) { v=u; } } if(v==-1) return; has[v]=true; for(int u=0;u<n;u++) { if(dis[u]>dis[v]+G[v][u]) { dis[u]=dis[v]+G[v][u]; ppath[u]=v; } else if((dis[u]==dis[v]+G[v][u]) && dis[v] &&(v!=u)) { int cntyuan=jiedian(u); int cntnew=jiedian(v)+1; if(cntnew<cntyuan) { dis[u]=dis[v]+G[v][u]; ppath[u]=v; } } } }}int distance(int u){ int tmp=0; while(path[u]!=s) { tmp+=G[path[u]][u]; u=path[u]; } tmp+=G[s][u]; return tmp;}void Dijkstra(){ fill(t,t+n,INF); fill(used,used+n,false); memset(path,-1,sizeof(path)); t[s]=0; while(1) { int v=-1; for(int u=0;u<n;u++) { if((v==-1 || t[u]<t[v]) &&!used[u]) { v=u; } } if(v==-1) return; used[v]=true; for(int u=0;u<n;u++) { if(t[u]>t[v]+M[v][u]) { t[u]=t[v]+M[v][u]; path[u]=v; } else if((t[u]==t[v]+M[v][u]) &&t[v]) { int oridis=distance(u); int newdis=distance(v); newdis=newdis+G[v][u]; if(newdis<oridis) { t[u]=t[v]+M[v][u]; path[u]=v; } } } }}int path1[505];int cnt1;int path2[505];int cnt2;void Recover(){ int u=e; while(u!=s) { path1[cnt1++]=u; u=path[u]; } path1[cnt1++]=u; reverse(path1,path1+cnt1); u=e; while(u!=s) { path2[cnt2++]=u; u=ppath[u]; } path2[cnt2++]=u; reverse(path2,path2+cnt2);}bool judge(){ if(cnt1!=cnt2) return false; for(int i=0;i<cnt1;i++) { if(path1[i]!=path2[i]) return false; } return true;}int TIME(){ int tmp=0; for(int i=0;i<cnt1-1;i++) { tmp+=M[path1[i]][path1[i+1]]; } return tmp;}int DIS(){ int tmp=0; for(int i=0;i<cnt2-1;i++) { tmp+=G[path2[i]][path2[i+1]]; } return tmp;}int main(){ scanf("%d%d",&n,&m); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { G[i][j]=M[i][j]=INF; } G[i][i]=M[i][i]=0; } for(int i=0;i<m;i++) { int x,y,z,l,t; scanf("%d%d%d%d%d",&x,&y,&z,&l,&t); if(z==1) { G[x][y]=l; M[x][y]=t; } else { G[x][y]=G[y][x]=l; M[x][y]=M[y][x]=t; } } scanf("%d%d",&s,&e); Dijkstra(); Dijkstra2(); Recover(); int time=TIME(); int di=DIS(); if(judge()) { printf("Time = %d; Distance = %d: ",time,di); for(int i=0;i<cnt1;i++) { if(i==0) printf("%d",path1[i]); else printf(" => %d",path1[i]); } printf("\n"); } else { printf("Time = %d: ",time); for(int i=0;i<cnt1;i++) { if(i==0) printf("%d",path1[i]); else printf(" => %d",path1[i]); } printf("\n"); printf("Distance = %d: ",di); for(int i=0;i<cnt2;i++) { if(i==0) printf("%d",path2[i]); else printf(" => %d",path2[i]); } } return 0;}
0 0
- 天梯地图(Dijkstra变形)
- pta 天梯地图 (Dijkstra)
- 团体程序设计天梯赛 L3-007. 天梯地图 Dijkstra
- Emergency (dijkstra 变形)
- 天梯赛练习 天梯地图(SPFA)
- 天梯地图(30 分)
- 天梯地图(30 分)
- 团体程序设计天梯赛-练习集 L3-007. 天梯地图 最短路 dijkstra 解题报告
- poj3268(dijkstra算法变形)
- poj 1797(dijkstra变形)
- 7-14 天梯地图(30 分)
- hiho二十三周(Dijkstra变形)
- POJ 1724 Roads(dijkstra变形)
- POJ 1797 Heavy Transportation(dijkstra变形)
- POJ 2253 Frogger(dijkstra变形)
- POJ 2253 - Frogger(dijkstra变形)
- poj 2253 Frogger(dijkstra变形)
- CSU 1808 地铁(Dijkstra变形+构图)
- 476. Number Complement (C++)
- UVA.12096 The SetStack Computer ( 好题 栈 STL混合应用)
- Solr配置文件及SolrCloud
- 使用服务注册特殊广播接收者
- java的日志管理
- 天梯地图(Dijkstra变形)
- 完整java开发中JDBC连接数据库代码和步骤
- Eclipse中常用的快捷键
- 蓝桥杯 进制转换三题 BASIC-10~BASIC-12
- 访问者模式
- python 函数的缺省参数的注意事项
- Android 播放视频
- js判断鼠标单击或者双击事件
- 67.android布局-Fragment与Activity之间传递数据