PAT Advanced 1030 Travel Plan (30) [Dijkstra算法 + DFS,最短路径,边权]
题目
A traveler’s map gives the distances between cities along the highways, together with the cost of each highway. Now you are supposed to write a program to help a traveler to decide the shortest path between his/her starting city and the destination. If such a shortest path is not unique, you are supposed to output the one with the minimum cost, which is guaranteed to be unique.
Input Specification:
Each input file contains one test case. Each case starts with a line containing 4 positive integers N, M, S, and D, where N (<=500) is the number of cities (and hence the cities are numbered from 0 to N-1); M is the number of highways; S and D are the starting and the destination cities, respectively. Then M lines follow, each provides the information of a highway, in the format:
City1 City2 Distance Cost
where the numbers are all integers no more than 500, and are separated by a space.
Output Specification:
For each test case, print in one line the cities along the shortest path from the starting point to the destination, followed by the total distance and the total cost of the path. The numbers must be separated by a space and there must be no extra space at the end of output.
Sample Input
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
Sample Output
0 2 3 3 40
题意
地图上显示了城市间高速公路的距离和费用,计算起点到终点距离最短的路线,如果有多条距离最短路线,取费用最低的最短路线
题目分析
已知图的顶点、边、两种边权(距离和费用),求单源带权最短路径,要求距离最短,若距离最短路径有多条,取费用最低的最短路径
解题思路
- 存储图信息
邻接矩阵
邻接表 - 求最短路径
2.1 dijkstra算法,求距离最短路径的同时,求出距离最短并且费用最少的最短路径
2.2 dijkstra算法,求出所有距离最短路径并存储,dfs遍历所有距离最短路径,求出距离最短并且费用最少的最短路径
int gw[maxn][maxn] //记录边权-距离
int ct[maxn][maxn] //记录边权-费用
int dist[maxn] //dijkstra记录从源点到其他顶点的最短距离
int path[maxn] //dijskstra记录最短距离路径
int act[maxn] //dijskstra记录从源点到其他顶点的最少费用
int col[maxn] //标记已收集到最短路径中的顶点
- 打印最短路径
3.1 利用栈(先进后出)
3.2 dfs
Code
Code 01(邻接矩阵 dijskstra求距离最短费用最少路径)
#include <iostream>
#include <stack>
using namespace std;
const int maxn=510;
const int INF=0x7fffffff;
int n,s,d,gw[maxn][maxn],ct[maxn][maxn];// gw边权-距离;ct边权-费用
int dist[maxn],path[maxn],act[maxn]; //act 总边权-总费用;
int col[maxn];//col 已收集到最短路径标记
/* dijkstra 求单源带权最短路径 */
void dijkstra(int x) {
/*1 初始化*/
fill(dist,dist+maxn,INF);
fill(act,act+maxn,INF);
fill(path,path+maxn,-1);
dist[x]=0;
act[x]=0;
for(int j=0; j<n; j++) {
/*2 查找最小dist*/
int mind=INF,min=-1;
for(int i=0; i<n; i++) {
if(col[i]==0 && dist[i]<mind) {
mind=dist[i];
min=i;
}
}
if(min==-1||min==d)break;
col[min]=1;
/*3 最小路径*/
for(int i=0; i<n; i++) {
if(gw[min][i]==0||col[i]==1)continue;
if(dist[i]>dist[min]+gw[min][i]) {
dist[i]=dist[min]+gw[min][i];
path[i]=min;
act[i]=act[min]+ct[min][i];
} else if(dist[i]==dist[min]+gw[min][i]&&act[i]>act[min]+ct[min][i]) {
path[i]=min;
act[i]=act[min]+ct[min][i];
}
}
}
}
/* 打印最短路径 方法一*/
void dfs(int y) {
if(y==-1)return;
dfs(path[y]);
printf("%d ",y);
}
/* 打印最短路径 方法二*/
//void ppt(int y) {
// stack<int> sk;
// int p=y;
// while(p!=-1) {
// sk.push(p);
// p=path[p];
// }
// while(!sk.empty()) {
// printf("%d ",sk.top());
// sk.pop();
// }
//}
int main(int argc,char * argv[]) {
int m,a,b;
scanf("%d %d %d %d",&n,&m,&s,&d);
for(int i=0; i<m; i++) {
scanf("%d %d",&a,&b);
scanf("%d",&gw[a][b]);
scanf("%d",&ct[a][b]);
gw[b][a]=gw[a][b];
ct[b][a]=ct[a][b];
}
dijkstra(s);
dfs(d);
// ppt(d);
printf("%d %d",dist[d],act[d]);
return 0;
}
Code 02(邻接矩阵 dijkstra求最短距离路径 dfs求最少费用路径)
#include <iostream>
#include <vector>
using namespace std;
const int INF=0x7fffffff;
const int maxn = 510;
int gw[maxn][maxn],ct[maxn][maxn];
int dist[maxn],path[maxn],act[maxn],col[maxn];
int n,m,s,d,minct=INF;
vector<int> pre[maxn],tempth,fp;
void dijkstra(int v) {
fill(dist,dist+maxn,INF);
fill(path,path+maxn,-1);
fill(act,act+maxn,INF);
dist[v]=0;
act[v]=0;
for(int i=0; i<n; i++) {
int min=-1,mind=INF;
for(int j=0; j<n; j++) {
if(col[j]==0&&dist[j]<mind) {
mind=dist[j];
min=j;
}
}
if(min==-1||min==d)break;
col[min]=1;
for(int j=0; j<n; j++) {
if(gw[min][j]==0||col[j]==1)continue;
if(dist[min]+gw[min][j]<dist[j]) {
dist[j]=dist[min]+gw[min][j];
path[j]=min;
pre[j].clear();
pre[j].push_back(min);
} else if(dist[min]+gw[min][j]==dist[j]) {
path[j]=min;
pre[j].push_back(min);
}
}
}
}
void dfs(int u) {
if(u==s) {
tempth.push_back(u);
int tempct=0;
for(int i=tempth.size()-1; i>=1; i--) {
tempct+=ct[tempth[i]][tempth[i-1]];
}
if(minct>tempct) {
minct=tempct;
fp = tempth;
}
tempth.pop_back();
return;
}
tempth.push_back(u);
for(int i=0; i<pre[u].size(); i++) {
dfs(pre[u][i]);
}
tempth.pop_back();
}
int main(int argc,char * argv[]) {
scanf("%d %d %d %d",&n,&m,&s,&d);
int a,b;
for(int i=0; i<m; i++) {
scanf("%d %d",&a,&b);
scanf("%d",&gw[a][b]);
scanf("%d",&ct[a][b]);
gw[b][a]=gw[a][b];
ct[b][a]=ct[a][b];
}
dijkstra(s);
dfs(d);
for(int i=fp.size()-1; i>=0; i--) {
printf("%d ",fp[i]);
}
printf("%d %d",dist[d],minct);
return 0;
}
Code 03(邻接表 dijskstra求距离最短费用最少路径)
#include <iostream>
#include <vector>
using namespace std;
const int maxn=510;
const int INF=0x7fffffff;
int n,s,d;// gw边权-距离;ct边权-费用
int dist[maxn],path[maxn],act[maxn]; //act 总边权-总费用;
int col[maxn];//col 已收集到最短路径标记
struct node{
int v;
int sw; //距离
int cw; //费用
};
vector<node> g[maxn];
/* dijkstra 求单源带权最短路径 */
void dijkstra(int x) {
/*1 初始化*/
fill(dist,dist+maxn,INF);
fill(act,act+maxn,INF);
fill(path,path+maxn,-1);
dist[x]=0;
act[x]=0;
for(int j=0; j<n; j++) {
/*2 查找最小dist*/
int mind=INF,min=-1;
for(int i=0; i<n; i++) {
if(col[i]==0 && dist[i]<mind) {
mind=dist[i];
min=i;
}
}
if(min==-1||min==d)break;
col[min]=1;
/*3 最小路径*/
for(int i=0; i<g[min].size(); i++) {
node u=g[min][i];
if(col[u.v]==1)continue;
if(dist[u.v]>dist[min]+u.sw) {
dist[u.v]=dist[min]+u.sw;
path[u.v]=min;
act[u.v]=act[min]+u.cw;
} else if(dist[u.v]==dist[min]+u.sw&&act[u.v]>act[min]+u.cw) {
path[u.v]=min;
act[u.v]=act[min]+u.cw;
}
}
}
}
/* 打印最短路径 方法一*/
void dfs(int y) {
if(y==-1)return;
dfs(path[y]);
printf("%d ",y);
}
/* 打印最短路径 方法二*/
//void ppt(int y) {
// stack<int> sk;
// int p=y;
// while(p!=-1) {
// sk.push(p);
// p=path[p];
// }
// while(!sk.empty()) {
// printf("%d ",sk.top());
// sk.pop();
// }
//}
int main(int argc,char * argv[]) {
int m,a,b,sw,cw;
scanf("%d %d %d %d",&n,&m,&s,&d);
for(int i=0; i<m; i++) {
scanf("%d %d",&a,&b);
scanf("%d",&sw);
scanf("%d",&cw);
g[a].push_back({b,sw,cw});
g[b].push_back({a,sw,cw});
}
dijkstra(s);
dfs(d);
// ppt(d);
printf("%d %d",dist[d],act[d]);
return 0;
}
Code 04 (邻接表 dijkstra求最短距离路径 dfs求最少费用路径)
因为该求解方法,dfs中需要根据顶点a,b寻找边,若使用邻接表,需要遍历g[a]的所有有关联的顶点,找到b的node
非要使用邻接表可以使用map<int,node> g[maxn];
PAT Advanced 1030 Travel Plan (30) [Dijkstra算法 + DFS,最短路径,边权]的更多相关文章
- PAT Advanced 1111 Online Map (30) [Dijkstra算法 + DFS]
题目 Input our current position and a destination, an online map can recommend several paths. Now your ...
- PAT 甲级 1030 Travel Plan (30 分)(dijstra,较简单,但要注意是从0到n-1)
1030 Travel Plan (30 分) A traveler's map gives the distances between cities along the highways, to ...
- PAT A 1030. Travel Plan (30)【最短路径】
https://www.patest.cn/contests/pat-a-practise/1030 找最短路,如果有多条找最小消耗的,相当于找两次最短路,可以直接dfs,数据小不会超时. #incl ...
- PAT Advanced 1072 Gas Station (30) [Dijkstra算法]
题目 A gas station has to be built at such a location that the minimum distance between the station an ...
- PAT-1030 Travel Plan (30 分) 最短路最小边权 堆优化dijkstra+DFS
PAT 1030 最短路最小边权 堆优化dijkstra+DFS 1030 Travel Plan (30 分) A traveler's map gives the distances betwee ...
- [图算法] 1030. Travel Plan (30)
1030. Travel Plan (30) A traveler's map gives the distances between cities along the highways, toget ...
- PAT Advanced 1018 Public Bike Management (30) [Dijkstra算法 + DFS]
题目 There is a public bike service in Hangzhou City which provides great convenience to the tourists ...
- 1030 Travel Plan (30)(30 分)
A traveler's map gives the distances between cities along the highways, together with the cost of ea ...
- PAT (Advanced Level) 1030. Travel Plan (30)
先处理出最短路上的边.变成一个DAG,然后在DAG上进行DFS. #include<iostream> #include<cstring> #include<cmath& ...
随机推荐
- hdu 1533 Going Home 最小费用最大流 (模板题)
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- OO第三次博客作业(第三单元总结)
(1)梳理JML语言的理论基础.应用工具链情况 Java 建模语言(JML)将注释添加到 Java 代码中,这样我们就可以确定方法所执行的内容,而不必说明它们如何做到这一点.有了 JML,我们就可以描 ...
- 深入解读EOS源代码之——区块链内核
EOS进入大众视野并且受到热议已经有一段时间了,各种热捧和争议过后,是时候让我们静下来搞清楚EOS到底是一个什么样的产品.本文从技术角度深入的分析EOS底层设计,从源代码入手,一层层揭开EOS区块链底 ...
- VMware Tools 组件、配置选项和安全要求
- 12.redis的AOF持久化深入讲解各种操作和相关实验
1.AOF持久化的配置 2.AOF持久化的数据恢复实验3.AOF rewrite4.AOF破损文件的修复5.AOF和RDB同时工作 ---------------------------------- ...
- PG、GP与MySQL的特点和区别
参考 PostgreSQL数据库 介绍:PostgreSQL是一种运行在Unix和Linux操作系统(在NT平台借助Cygnus也可以运行)平台上的免费的开放源码的关系数据库.最早是由美国加州大学伯克 ...
- 看完本文,Essay写作再也不需要凑字数
很多同学都说过自己写论文的时候出现“词穷”的情况,无奈只能靠“胡编乱造”来凑字数写出开头段,这其实是大家的阅读量没有达到要求.但不能因为出现这种情况就对自己的论文不负责任,否则你的论文分数可能就不会对 ...
- JuJu团队12月2号工作汇报
JuJu团队12月2号工作汇报 JuJu Scrum 团队成员 今日工作 剩余任务 困难 于达 和婷婷一起调试main.jl 继续调试 金华实现的BiLSTM参数无法使用save存入 婷婷 和于达 ...
- UVA - 712 S-Trees(S树)
题意:0往左走,1往右走,已知所有叶子的值,每个查询都是根结点到叶子结点的路径,路径的每一个点分别对应着x1,x2,x3……但是实际上的S树的路径可能并非是x1,x2,x3…… 分析:先存路径变量的顺 ...
- 文件上传报错java.io.FileNotFoundException拒绝访问
局部代码如下: File tempFile = new File("G:/tempfileDir"+"/"+fileName); if(!tempFile.ex ...