7-9 旅游规划 (25 分)Dijkstra算法,单源最短路径算法
有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。
输入格式:
输入说明:输入数据的第1行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N−1);M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。输入保证解的存在。
输出格式:
在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。
输入样例:
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
结尾无空行
输出样例:
3 40
这题就是一道简单的Dijkstra最短路径算法题,甚至连代码中的path都不需要了,因为它不需要输出最短路径是怎么走的,只需输出最短路径的值。但是题目虽然简单,我还是犯了不少错误。
首先第一点,经典Dijkstra算法是判断一个权重,但是在这道题目里面,你要同时考虑最短路径和最小花费,得到最优解,这里就需要对原来的Dijkstra算法做一个小小的变形;
原来的代码是这样的,仅仅找最短路径:
if (dist[temp][j] < INF && distanc[temp] + dist[temp][j] < distanc[j]){distanc[j] = distanc[temp] + dist[temp][j];cost[j] = cost[temp] + Cost[temp][j];path[j]=temp;//这里找到temp的邻接点,然后判断是否存在更短的路径,可以的话进行调换 }
现在还要加一个判断条件,当路径相同时选取最小花费,代码如下:
if (dist[temp][j] < INF && distanc[temp] + dist[temp][j] < distanc[j]){distanc[j] = distanc[temp] + dist[temp][j];cost[j] = cost[temp] + Cost[temp][j];path[j]=temp;//这里找到temp的邻接点,然后判断是否存在更短的路径,可以的话进行调换 }else if(dist[temp][j] < INF && distanc[temp] + dist[temp][j] == distanc[j]&&cost[temp] + Cost[temp][j] < cost[j])//这里一开始没有写cost[temp] + Cost[temp][j] < cost[j]这个判断条件,然后只有前两项是通过的,一定要路费最少才能走{cost[j] = cost[temp] + Cost[temp][j];distanc[j] = distanc[temp] + dist[temp][j];path[j]=temp;}//这里其实不需要更新distanc,因为距离是等长的
这就是这道题的核心所在。
然后,把distanc和cost存储在二维数组里面时,需要在主函数里面对其所有元素进行初始化,初始化为INF,不能在定义时初始化,是没有用的
即这样在全局定义时进行初始化是没有用的,得到的结果是部分正确:
int dist[MaxSize][MaxSize]={INF};//这样初始化是没有用的
int Cost[MaxSize][MaxSize]={INF};
需要在主函数里面这样才能有用:
for(int i=0;i<N;i++)//这里不能在定义的时候初始化,会出现问题,必须写一个循环初始化for (int j = 0;j < N;j++){dist[i][j] = INF;Cost[i][j] = INF;}
还有出现的一个低级错误是当路径相等时,忘了写判断条件选取最便宜的那一天路径,这样的话只通过了前面的简单用例,即如下,忘了一个判断条件:
if (dist[temp][j] < INF && distanc[temp] + dist[temp][j] < distanc[j])
{distanc[j] = distanc[temp] + dist[temp][j];cost[j] = cost[temp] + Cost[temp][j];path[j] = temp;//这里找到temp的邻接点,然后判断是否存在更短的路径,可以的话进行调换
}
else if (dist[temp][j] < INF && distanc[temp] + dist[temp][j] == distanc[j])//这里一开始没有写cost[temp] + Cost[temp][j] < cost[j]这个判断条件,然后只有前两项是通过的,一定要路费最少才能走
{cost[j] = cost[temp] + Cost[temp][j];distanc[j] = distanc[temp] + dist[temp][j];path[j] = temp;
}
//这里其实不需要更新distanc,因为距离是等长的
完整的代码如下:
#include<iostream>
using namespace std;
const int INF = 65535;
const int MaxSize = 501;
int dist[MaxSize][MaxSize]={INF};//这样初始化是没有用的
int Cost[MaxSize][MaxSize];
//Dijkstra算法描述,单源最短路径算法
void Dijkstra(int v,int N,int D)
{int distanc[MaxSize], cost[MaxSize],path[MaxSize],temp=v;int S[MaxSize];for (int i = 0;i <N;++i){distanc[i] = dist[v][i];cost[i] = Cost[v][i];S[i] = 0;//表示暂时还没有顶点被处理过,不在S里面if(dist[v][i]<INF)path[i]=v;elsepath[i]=-1;}S[v] = 1;//这里path[v]=0是否不需要?,S[v]=1表示v在S里面了,v已经处理了//循环直到把所以点放入S中,得到最终最短路径for (int i = 0;i <N-1;++i){int MINdis = INF;//把最短距离初始化为最大for (int j = 0;j <N;++j)//找出不在S中且距离v最近的顶点uif (S[j] == 0 && distanc[j] < MINdis){temp = j;MINdis = distanc[j];//这样不停置换就可以得到最小的distanc对应的temp}S[temp] = 1;//然后堆temp的邻接点进行操作,更新最短路径for (int j = 0;j <N;++j)if (S[j] == 0)//表示没有被处理过的,可以用来更新的j点{if (dist[temp][j] < INF && distanc[temp] + dist[temp][j] < distanc[j]){distanc[j] = distanc[temp] + dist[temp][j];cost[j] = cost[temp] + Cost[temp][j];path[j]=temp;//这里找到temp的邻接点,然后判断是否存在更短的路径,可以的话进行调换 }else if(dist[temp][j] < INF && distanc[temp] + dist[temp][j] == distanc[j]&&cost[temp] + Cost[temp][j] < cost[j])//这里一开始没有写cost[temp] + Cost[temp][j] < cost[j]这个判断条件,然后只有前两项是通过的,一定要路费最少才能走{cost[j] = cost[temp] + Cost[temp][j];distanc[j] = distanc[temp] + dist[temp][j];path[j]=temp;}//这里不需要更新distanc,因为距离是等长的}}cout << distanc[D] << " " << cost[D] << endl;
}
int main()
{int N, M, S, D;cin >> N >> M >> S >> D;int city1, city2, length, fee;for(int i=0;i<N;i++)//这里不能在定义的时候初始化,会出现问题,必须写一个循环初始化for (int j = 0;j < N;j++){dist[i][j] = INF;Cost[i][j] = INF;}for (int i = 0;i < M;++i){cin >> city1 >> city2 >> length >> fee;dist[city1][city2] = length;dist[city2][city1] = length;Cost[city1][city2] = fee;Cost[city2][city1] = fee;}for(int i=0;i<N;i++){dist[i][i]=0;Cost[i][i]=0;}Dijkstra(S,N,D);
}
7-9 旅游规划 (25 分)Dijkstra算法,单源最短路径算法相关推荐
- Dijkstra(迪杰斯特拉)算法(单源最短路径算法)的理解
介绍 对于dijkstra算法,很多人可能感觉熟悉而又陌生,可能大部分人比较了解bfs和dfs,而对dijkstra和floyd算法可能知道大概是图论中的某个算法,但是可能不清楚其中的作用和原理,又或 ...
- 图的最短路径之Dijkstra求单源最短路径算法(C++)
一个有向带权图求它的单源最短路径可以使用Dijkstra算法. 单源最短路径是指:从图中的某个顶点出发,到其余各个顶点权值最小的路径. Dijkstra算法需要用到三个辅助数组: dist[max]: ...
- [召集令]-Dijkstra的单源最短路径算法
2021.3.10 题目背景 墨家家主发出召集令,所有弟子得迅速到指定地点集合. 题目描述 给定一张地图,含有n个地点(n<=10000),地点从1开始编号,地图上还含有m条单向路(m<= ...
- PTA 7-3 旅游规划 (25分)(双权值Dijkstra最短路)
7-3 旅游规划 (25分) 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干条路 ...
- 【dijkstra模板】旅游规划 (25 分)
立志用最少的代码做最高效的表达 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干条 ...
- 7-3 旅游规划 (25 分)(C语言实现)
有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干条路径都是最短的,那么需要输出最便 ...
- 案例6-1.5 旅游规划 (25 分)邻接表实现
案例6-1.5 旅游规划 (25 分) 用邻接表实现Dijkstra算法 这题一开始做的时候没想到用邻接数组做,所以就用的链表. 总的来说还是Dijkstra算法,只不过是存储方式的问题罢了,我用了四 ...
- 7-2 旅游规划 (25分)
7-2 旅游规划 (25分) 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干条路 ...
- PTA 07-图6 旅游规划 (25分)
题目地址 https://pta.patest.cn/pta/test/15/exam/4/question/717 5-9 旅游规划 (25分) 有了一张自驾旅游路线图,你会知道城市间的高速公路 ...
- 7-图6 旅游规划 (25 分)
7-图6 旅游规划 (25 分) 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干 ...
最新文章
- AI 四巨头 Google、DeepMind、Microsoft、Uber 深度学习框架大比拼
- linux一个进程通知另外一个进程,Linux进程通信学习笔记
- linux c socket 服务器 客户端 简单通讯
- python 命令行参数-Python 获得命令行参数的方法(推荐)
- P3321 [SDOI2015]序列统计(未解决)
- 四、Spring中使用@Conditional按照条件注册Bean
- SSL 1105——【USACO 2.1】顺序的分数(递归+二分)
- 根据输入参数创建xml模板
- AR的那些有用的工具
- MFC最详细入门教程[转载]
- Xposed安装与使用
- BBRv2 Cruise 阶段的 inflight 补偿
- 大数据还能火多久?现在学习还来得及吗?
- 机器学习入门——简单线性回归
- LODOP打印控件使用问题总结
- 【FLUENT案例】01:T型管混合器中的流动与传热
- PO, AP, GL Open/Closed Period Action
- 城中村、小区WiFi覆盖方案
- 智慧建造管理平台施工现场视频监控系统
- 异响加持、吐槽声不断,小鹏G9难解困局
热门文章
- 2016.10.9晨记
- security update 补丁更新失败
- Mysql创建用户并赋予权限
- destoon标签调用技巧
- Task watchdog got triggered错误
- 从零起步做到Linux运维经理,你必须管好的23个细节
- Error creating bean with name ‘serverEndpointExporter‘ defined in class path resource
- 触动精灵--点击函数封装--一些特殊情况的使用--狂暴传奇
- linux识别riser卡,一种具有多接口的Riser卡的制作方法
- python汇率换算程序_Python编写一个汇率兑换程序