【PAT】1111. Online Map (30)【dijkstra算法】

2024-04-12 06:08

本文主要是介绍【PAT】1111. Online Map (30)【dijkstra算法】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目描述

Input our current position and a destination, an online map can recommend several paths. Now your job is to recommend two paths to your user: one is the shortest, and the other is the fastest. It is guaranteed that a path exists for any request.

翻译:输入我们当前的位置和目的地,一个在线地图可以推荐几个路径。现在您的任务是向用户推荐两条路径:一条是最短的,另一条是最快的。数据保证任何请求都存在一条路径。

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive integers N (2≤N≤500), and M, being the total number of streets intersections on a map, and the number of streets, respectively. Then M lines follow, each describes a street in the format:

V1 V2 one-way length time
where V1 and V2 are the indices (from 0 to N−1) of the two ends of the street; one-way is 1 if the street is one-way from V1 to V2, or 0 if not; length is the length of the street; and time is the time taken to pass the street.

Finally a pair of source and destination is given.

翻译:每个输入文件包含一组测试数据。对于每组输入数据,第一行包括两个正整数N(2≤N≤500), 和M,分别表示代表地图上道路的交叉点的总数量和道路数量。接下来M行,每行按照以下格式描述一条道路:
V1 V2 one-way length time
V1和V2是道路的两个末端索引(从0到N-1),one-way如果为1代表是从v1到v2的单行道,0则不是。length代表的是街道的长度;time代表通过这条街道所需的试卷。
最后给出一对起点和终点。

Output Specification:

For each case, first print the shortest path from the source to the destination with distance D in the format:

Distance = D: source -> v1 -> … -> destination
Then in the next line print the fastest path with total time T:

Time = T: source -> w1 -> … -> destination
In case the shortest path is not unique, output the fastest one among the shortest paths, which is guaranteed to be unique. In case the fastest path is not unique, output the one that passes through the fewest intersections, which is guaranteed to be unique.

In case the shortest and the fastest paths are identical, print them in one line in the format:

Distance = D; Time = T: source -> u1 -> … -> destination

翻译:对于每组输入数据,第一行按照以下格式输出从起点到终点的最短路及其长度D:
Distance = D: source -> v1 -> … -> destination

接下来一行输出最快的路及其时间T:
Time = T: source -> w1 -> … -> destination

万一最短路不唯一,输出最短路中最快的那一条,数据保证结果唯一。万一最快的路不唯一,输出经过的交叉点最少的那一条,数据保证结果唯一。
万一最短路和最快的路相同,按照以下格式输出一行:
Distance = D; Time = T: source -> u1 -> … -> destination


Sample Input 1:

10 15
0 1 0 1 1
8 0 0 1 1
4 8 1 1 1
3 4 0 3 2
3 9 1 4 1
0 6 0 1 1
7 5 1 2 1
8 5 1 2 1
2 3 0 2 2
2 1 1 1 1
1 3 0 3 1
1 4 0 1 1
9 7 1 3 1
5 1 0 5 2
6 5 1 1 2
3 5


Sample Output 1:

Distance = 6: 3 -> 4 -> 8 -> 5
Time = 3: 3 -> 1 -> 5


Sample Input 2:

7 9
0 4 1 1 1
1 6 1 1 3
2 6 1 1 1
2 5 1 2 2
3 0 0 1 1
3 1 1 1 3
3 2 1 1 2
4 5 0 2 2
6 5 1 1 2
3 5


Sample Output 2:

Distance = 3; Time = 4: 3 -> 2 -> 5


解题思路

用dijkstra方法搜索两遍即可,注意最短路节点要保存路程和时间,最快路节点要保存时间和经过的节点数,最后判断一下两条路径是否重合。这道题条件比较多,所以有些繁琐,需要仔细思考。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<vector>
#include<queue>
#include<algorithm>
#define INF 99999999
using namespace std;
int N,M;
int d[510][2],Lpre[510],Tpre[510],Lmin,Tmin;
int Lans[510],Tans[510],lcount=1,tcount=1;
int start,destination;
struct Edge{int nodes,time,to;Edge(int a,int b,int c):nodes(a),time(b),to(c){}bool operator<(const Edge tmp)const{if(time==tmp.time) return nodes>tmp.nodes;return time>tmp.time;}
};
struct LengthEdge{int length,time,to;LengthEdge(int a,int b,int c):length(a),time(b),to(c){}bool operator<(const LengthEdge tmp)const{if(length==tmp.length) return time>tmp.time;else  return length>tmp.length;}
};
vector<LengthEdge> L[510];void Tdijkstra(int s){priority_queue<Edge> q;for(int i=0;i<N;i++){d[i][0]=d[i][1]=INF;Tpre[i]=-1;}d[s][0]=d[s][1]=0;q.push(Edge(0,0,s));while(!q.empty()){Edge temp=q.top();q.pop();int v=temp.to;if(d[v][0]<temp.time)continue;for(int i=0;i<L[v].size();i++){LengthEdge e=L[v][i];if(d[e.to][0]>d[v][0]+e.time){d[e.to][0]=d[v][0]+e.time;Tpre[e.to]=v;d[e.to][1]=d[v][1]+1;q.push(Edge(d[e.to][1],d[e.to][0],e.to));}else if(d[e.to][0]==d[v][0]+e.time){if(d[e.to][1]>d[v][1]+1){Tpre[e.to]=v;d[e.to][1]=d[v][1]+1;q.push(Edge(d[e.to][1],d[e.to][0],e.to));}}}}Tmin=d[destination][0];
}
void Ldijkstra(int s){priority_queue<LengthEdge> q;for(int i=0;i<N;i++){d[i][0]=d[i][1]=INF;Lpre[i]=-1;}d[s][0]=d[s][1]=0;q.push(LengthEdge(0,0,s));while(!q.empty()){LengthEdge temp=q.top();q.pop();int v=temp.to;if(d[v][0]<temp.length)continue;for(int i=0;i<L[v].size();i++){LengthEdge e=L[v][i];if(d[e.to][0]>d[v][0]+e.length){d[e.to][0]=d[v][0]+e.length;Lpre[e.to]=v;d[e.to][1]=d[v][1]+e.time;q.push(LengthEdge(d[e.to][0],d[e.to][1],e.to));}else if(d[e.to][0]==d[v][0]+e.length){if(d[e.to][1]>d[v][1]+e.time){d[e.to][0]=d[v][0]+e.length;Lpre[e.to]=v;d[e.to][1]=d[v][1]+e.time;q.push(LengthEdge(d[e.to][0],d[e.to][1],e.to));}}}}Lmin=d[destination][0];
}
void LgetPath(){int temp=Lans[0]=destination;lcount=1;while(Lpre[temp]!=-1){Lans[lcount++]=Lpre[temp];temp=Lpre[temp];}
}
void TgetPath(){int temp=Tans[0]=destination;tcount=1;while(Tpre[temp]!=-1){Tans[tcount++]=Tpre[temp];temp=Tpre[temp];}
}
void print(){int i;for(i=0;i<tcount;i++){if(Tans[i]!=Lans[i])break;}if(i==tcount){printf("Distance = %d; Time = %d: %d",Lmin,Tmin,start);for(i=tcount-2;i>=0;i--){printf(" -> %d",Lans[i]);}printf("\n");}else{printf("Distance = %d: %d",Lmin,start);for(i=lcount-2;i>=0;i--){printf(" -> %d",Lans[i]);}printf("\n");printf("Time = %d: %d",Tmin,start);for(i=tcount-2;i>=0;i--){printf(" -> %d",Tans[i]);}printf("\n");		}
}
int main(){scanf("%d%d",&N,&M);int a,b,c,d,e;for(int i=0;i<M;i++){scanf("%d%d%d%d%d",&a,&b,&c,&d,&e);L[a].push_back(LengthEdge(d,e,b));if(c!=1){L[b].push_back(LengthEdge(d,e,a));}}scanf("%d%d",&start,&destination);Ldijkstra(start);Tdijkstra(start);LgetPath();TgetPath();print();return 0;
}

这篇关于【PAT】1111. Online Map (30)【dijkstra算法】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/896311

相关文章

Java中Map.Entry()含义及方法使用代码

《Java中Map.Entry()含义及方法使用代码》:本文主要介绍Java中Map.Entry()含义及方法使用的相关资料,Map.Entry是Java中Map的静态内部接口,用于表示键值对,其... 目录前言 Map.Entry作用核心方法常见使用场景1. 遍历 Map 的所有键值对2. 直接修改 Ma

Java中JSON格式反序列化为Map且保证存取顺序一致的问题

《Java中JSON格式反序列化为Map且保证存取顺序一致的问题》:本文主要介绍Java中JSON格式反序列化为Map且保证存取顺序一致的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未... 目录背景问题解决方法总结背景做项目涉及两个微服务之间传数据时,需要提供方将Map类型的数据序列化为co

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

Springboot实现推荐系统的协同过滤算法

《Springboot实现推荐系统的协同过滤算法》协同过滤算法是一种在推荐系统中广泛使用的算法,用于预测用户对物品(如商品、电影、音乐等)的偏好,从而实现个性化推荐,下面给大家介绍Springboot... 目录前言基本原理 算法分类 计算方法应用场景 代码实现 前言协同过滤算法(Collaborativ

Java使用Stream流的Lambda语法进行List转Map的操作方式

《Java使用Stream流的Lambda语法进行List转Map的操作方式》:本文主要介绍Java使用Stream流的Lambda语法进行List转Map的操作方式,具有很好的参考价值,希望对大... 目录背景Stream流的Lambda语法应用实例1、定义要操作的UserDto2、ListChina编程转成M

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

SpringBoot如何通过Map实现策略模式

《SpringBoot如何通过Map实现策略模式》策略模式是一种行为设计模式,它允许在运行时选择算法的行为,在Spring框架中,我们可以利用@Resource注解和Map集合来优雅地实现策略模式,这... 目录前言底层机制解析Spring的集合类型自动装配@Resource注解的行为实现原理使用直接使用M

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时