案例6-1.5 旅游规划

  • 题目
  • 解法

题目

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

输入格式:
输入说明:输入数据的第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

解法

思路

  1. 这是一道基本的单源最短路径问题。注意单源最短路径问题中,源点到某一特定点的最短路径的时间复杂度源点到所有点的最短路径的时间复杂度相同
  2. 这里涉及到的操作有:初始化一个空图(用邻接矩阵实现,动态数组)、插入边、构建图,dijkstra算法。初始化空图时,权重的数据类型应该是一个结构体,既能存储长度距离,又能存储费用。
  3. 在dijkstra算法中,寻找下一顶点V的时候,仍然按照最小距离寻找,只不过在更新dist、cost、path这三个数组的时候,需要注意,
    距离的优先级是最高的,如果dist[W]因为添加V变小了,那么一定要进行更新。
    其次是距离相等的时候,cost[W]变小了就更新,否则cost不更新.

注意:
对于源点,collected[S]一定要赋值为1,而dist[S]不一定要赋值为0,因为collected[S]=0会导致后面在FindMinDist函数中也不会用到dist[S]。cost[S]和dist[S]同理

实现

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>#define INFINITY 100000
#define ERROR -2typedef int Vertex;struct Weight
{int Length;int Fee;
};
typedef struct Weight WeightType;typedef struct GNode *PtrToGNode;
typedef PtrToGNode MGraph;
struct GNode
{int Nv;int Ne;WeightType **G;
};typedef struct ENode *PtrToENode;
typedef PtrToENode Edge;
struct ENode
{Vertex V1, V2;WeightType W;
};MGraph CreateGraph(int VertexNum)
{MGraph Graph = (MGraph)malloc(sizeof(struct GNode));Graph->Nv = VertexNum;//allocate the roomint i,j;Graph->G = (WeightType **)malloc(Graph->Nv*sizeof(WeightType *));for(i=0; i<Graph->Nv; i++){Graph->G[i] = (WeightType *)malloc(Graph->Nv*sizeof(WeightType));}//initialfor(i=0; i<Graph->Nv; i++)for(j=0; j<Graph->Nv; j++){Graph->G[i][j].Length = INFINITY;Graph->G[i][j].Fee = INFINITY;}return Graph;
}void InsertEdge(MGraph Graph, Edge E)
{Graph->G[E->V1][E->V2] = E->W;  //can assign it directlyGraph->G[E->V2][E->V1] = E->W;
}MGraph BuildGraph(int VertexNum, int EdgeNum)
{MGraph Graph = CreateGraph(VertexNum);Graph->Ne = EdgeNum;Edge E = (Edge)malloc(sizeof(struct ENode));int i;for(i=0; i<Graph->Ne; i++){scanf("%d %d %d %d", &E->V1, &E->V2, &E->W.Length, &E->W.Fee);InsertEdge(Graph, E);}return Graph;
}Vertex FindMinDist(MGraph Graph, int dist[], int collected[])
{Vertex MinV, V;int MinDist = INFINITY;for(V=0; V<Graph->Nv; V++){if(collected[V] == 0 && dist[V]<MinDist){MinDist = dist[V];MinV = V;}}if(MinDist == INFINITY)return ERROR;return MinV;}bool Dijkstra(MGraph Graph, int dist[], int path[], int cost[], Vertex S)
{int *collected = (int *)malloc(Graph->Nv*sizeof(int));Vertex V;for(V=0; V<Graph->Nv; V++){dist[V] = Graph->G[S][V].Length;cost[V] = Graph->G[S][V].Fee;if(dist[V] < INFINITY)path[V] = S;elsepath[V] = -1;collected[V] = 0;}// dist[S] = 0;collected[S] = 1;Vertex W;while(1){V = FindMinDist(Graph, dist, collected);if(V == ERROR)break;collected[V] = 1;for(W=0; W<Graph->Nv; W++){if(collected[W] == 0 && Graph->G[W][V].Length < INFINITY){if(Graph->G[W][V].Length<0)return false;if(dist[W] > dist[V]+Graph->G[W][V].Length || (dist[W] == dist[V]+Graph->G[W][V].Length && cost[W] > cost[V]+Graph->G[W][V].Fee)){dist[W] = dist[V]+Graph->G[W][V].Length;cost[W] = cost[V]+Graph->G[W][V].Fee;path[W] = V;}}}}return true;
}int main()
{int N,M;Vertex S,D;scanf("%d %d %d %d", &N, &M, &S, &D);MGraph Graph = BuildGraph(N, M);int *dist = (int *)malloc(Graph->Nv * sizeof(int));int *cost = (int *)malloc(Graph->Nv * sizeof(int));int *path = (int *)malloc(Graph->Nv * sizeof(int));Dijkstra(Graph, dist, path, cost, S);printf("%d %d", dist[D], cost[D]);return 0;
}

数据结构PTA 案例6-1.5 旅游规划相关推荐

  1. 【PAT数据结构与算法题目集】 旅游规划(单源最短路径,长度+路径查找)

    [PAT数据结构与算法题目集] 旅游规划(单源最短路径,长度+路径查找) 题目 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客 ...

  2. 数据结构PTA案例7-1.3 寻找大富翁

    案例7-1.3 寻找大富翁 1.题目 2.三种时间复杂度为O(N^2^)的解法 2.1 选择排序算法 2.2 插入排序算法 2.3 冒泡排序算法 3.时间复杂度为O(N*logN)的解法 3.1 快速 ...

  3. 数据结构PTA 案例6-1.6 哈利·波特的考试

    案例6-1.6 哈利·波特的考试 题目 解法 题目 哈利·波特要考试了,他需要你的帮助.这门课学的是用魔咒将一种动物变成另一种动物的本事.例如将猫变成老鼠的魔咒是haha,将老鼠变成鱼的魔咒是hehe ...

  4. 数据结构PTA 案例6-1.4 地下迷宫探索

    案例6-1.4 地下迷宫探索 题目 解法 题目 假设有一个地下通道迷宫,它的通道都是直的,而通道所有交叉点(包括通道的端点)上都有一盏灯和一个开关.请问你如何从某个起点开始在迷宫中点亮所有的灯并回到起 ...

  5. 数据结构PTA 案例5-1.4 字符串关键字的散列映射

    案例5-1.4 字符串关键字的散列映射 题目 解法 题目 给定一系列由大写英文字母组成的字符串关键字和素数P,用移位法定义的散列函数H(Key)将关键字Key中的最后3个字符映射为整数,每个字符占5位 ...

  6. PTA 数据结构与算法 7-9 旅游规划 (25 point(s))

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

  7. PTA 数据结构课程设计 7-10 旅游规划

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

  8. PTA 旅游规划(邻接矩阵) 思路分析及代码解析

    PTA 旅游规划 思路分析及代码解析v1.0 一.前导 1. 需要掌握的知识 2. 题目信息 二.解题思路分析 1. 题意理解 1. 1 输入数据 1.2 输出数据 2. 思路分析(重点) 三.具体实 ...

  9. PTA 旅游规划(邻接表) 思路分析及代码解析

    PTA 旅游规划_使用邻接表 思路分析及代码解析v1.0 一.前导 1. 需要掌握的知识 2. 题目信息 二.解题思路分析 1. 题意理解 1. 1 输入数据 1.2 输出数据 2. 思路分析(重点) ...

最新文章

  1. php7 ext skel_基于PHP7的PHP扩展开发之一(hello word)
  2. 2021护理正高考试成绩查询,中国卫生人才网:2021年护资考试成绩现可查询!
  3. 如何设置minSdkVersion和targetSdkVersion
  4. 接口转发和重定向区别(一)
  5. 熟读《阿里巴巴java开发手册》(二、异常日志)
  6. 乘基取整法是什么_十进制小数转二进制小数乘2取整法的直观理解
  7. 人工智能支撑马赛克战机理研究
  8. css hack的使用
  9. Maven 菜鸟教程 4 常用dos命令
  10. 刚刚!蚂蚁全部互联网存款产品下架;阿里辟谣:被中央联合调查纯属谣言!...
  11. SAP Transactions
  12. IE 代理服务器设置程序实现
  13. 大数据教孩子如何写好作文
  14. iOS内购-防越狱破解刷单
  15. Springsecurity+cas整合后无法单点登出
  16. Pohlig-Hellman算法解决DLP问题
  17. SegmentFault 思否发布开源问答社区软件 Answer
  18. 九章云极DataCanvas公司深度参编《中国金融科技发展报告2021》蓝皮书
  19. 2020最流行的Java构建和依赖管理工具:Maven
  20. snprintf 函数用法

热门文章

  1. 一定会在计算机领域取得成功英文,西子的英文考卷
  2. 带你实现java根据表结构动态导入导出Excel
  3. 【Python】爬虫(Xpath):批量爬取彼岸图网4K图(非真正4K)
  4. Unity Accelerator本地服务器加速Unity项目资源载入速度
  5. java iqq_iQQ 基于WebQQ3.0协议Java开发 跨平台QQ客户端
  6. python常用函数库-Python常用库大全及简要说明
  7. crypto-dirty laundry(zer0pts CTF 2020)
  8. 以太坊钱包私钥爆破产业链和攻击案例
  9. Cesium实现雷达扫描效果
  10. 对于LSM Tree写放大问题的一些浅薄学习