有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。

输入格式:
输入说明:输入数据的第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算法,单源最短路径算法相关推荐

  1. Dijkstra(迪杰斯特拉)算法(单源最短路径算法)的理解

    介绍 对于dijkstra算法,很多人可能感觉熟悉而又陌生,可能大部分人比较了解bfs和dfs,而对dijkstra和floyd算法可能知道大概是图论中的某个算法,但是可能不清楚其中的作用和原理,又或 ...

  2. 图的最短路径之Dijkstra求单源最短路径算法(C++)

    一个有向带权图求它的单源最短路径可以使用Dijkstra算法. 单源最短路径是指:从图中的某个顶点出发,到其余各个顶点权值最小的路径. Dijkstra算法需要用到三个辅助数组: dist[max]: ...

  3. [召集令]-Dijkstra的单源最短路径算法

    2021.3.10 题目背景 墨家家主发出召集令,所有弟子得迅速到指定地点集合. 题目描述 给定一张地图,含有n个地点(n<=10000),地点从1开始编号,地图上还含有m条单向路(m<= ...

  4. PTA 7-3 旅游规划 (25分)(双权值Dijkstra最短路)

    7-3 旅游规划 (25分) 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干条路 ...

  5. 【dijkstra模板】旅游规划 (25 分)

    立志用最少的代码做最高效的表达 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干条 ...

  6. 7-3 旅游规划 (25 分)(C语言实现)

    有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干条路径都是最短的,那么需要输出最便 ...

  7. 案例6-1.5 旅游规划 (25 分)邻接表实现

    案例6-1.5 旅游规划 (25 分) 用邻接表实现Dijkstra算法 这题一开始做的时候没想到用邻接数组做,所以就用的链表. 总的来说还是Dijkstra算法,只不过是存储方式的问题罢了,我用了四 ...

  8. 7-2 旅游规划 (25分)

    7-2 旅游规划 (25分) 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干条路 ...

  9. PTA 07-图6 旅游规划 (25分)

    题目地址 https://pta.patest.cn/pta/test/15/exam/4/question/717 5-9 旅游规划   (25分) 有了一张自驾旅游路线图,你会知道城市间的高速公路 ...

  10. 7-图6 旅游规划 (25 分)

    7-图6 旅游规划 (25 分) 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干 ...

最新文章

  1. AI 四巨头 Google、DeepMind、Microsoft、Uber 深度学习框架大比拼
  2. linux一个进程通知另外一个进程,Linux进程通信学习笔记
  3. linux c socket 服务器 客户端 简单通讯
  4. python 命令行参数-Python 获得命令行参数的方法(推荐)
  5. P3321 [SDOI2015]序列统计(未解决)
  6. 四、Spring中使用@Conditional按照条件注册Bean
  7. SSL 1105——【USACO 2.1】顺序的分数(递归+二分)
  8. 根据输入参数创建xml模板
  9. AR的那些有用的工具
  10. MFC最详细入门教程[转载]
  11. Xposed安装与使用
  12. BBRv2 Cruise 阶段的 inflight 补偿
  13. 大数据还能火多久?现在学习还来得及吗?
  14. 机器学习入门——简单线性回归
  15. LODOP打印控件使用问题总结
  16. 【FLUENT案例】01:T型管混合器中的流动与传热
  17. PO, AP, GL Open/Closed Period Action
  18. 城中村、小区WiFi覆盖方案
  19. 智慧建造管理平台施工现场视频监控系统
  20. 异响加持、吐槽声不断,小鹏G9难解困局

热门文章

  1. 2016.10.9晨记
  2. security update 补丁更新失败
  3. Mysql创建用户并赋予权限
  4. destoon标签调用技巧
  5. Task watchdog got triggered错误
  6. 从零起步做到Linux运维经理,你必须管好的23个细节
  7. Error creating bean with name ‘serverEndpointExporter‘ defined in class path resource
  8. 触动精灵--点击函数封装--一些特殊情况的使用--狂暴传奇
  9. linux识别riser卡,一种具有多接口的Riser卡的制作方法
  10. python汇率换算程序_Python编写一个汇率兑换程序