题目分析:

本题的题意比较清晰,就是有一个起点和一个终点,给出m条路径,可能是单向的可能是双向的,同时一条路有两个权重,分别是通过这条路需要的时间和这条路的路径长度,题目需要求出两条路径,一条是在最快的基础上的最短路径,一条是在最短的路径的基础上的通过节点的数量最少的路径(题目保证这两条途径存在,且在各自的情况下唯一,但是这两条路径有可能完全相同,需要合并输出)

解法分析:

通过对题目的分析,我们知道最优的子情况就是全局的最优解,所以我们用两次dijkstra算法,一次求最短路径的情况下通过最少节点的路径记录在pre1中,一次求最快路径的基础上的最短路径,记录在pre2中,最后递归输出路径即可

代码:

  1 #include<stdio.h>
2 #include<iostream>
3 #include<algorithm>
4 #include<cmath>
5 #include<string.h>
6 using namespace std;
7
8 const int N = 505;
9 const int M = 0x3f3f3f3f;
10 int pre1[N];
11 int pre2[N];
12 int dist1[N];
13 int dist2[N];
14 int mat1[N][N]; //存储距离
15 int mat2[N][N]; //存储时间
16 int vis1[N];
17 int vis2[N];
18 int num[N];
19 int n, m;
20 int min_dist, min_time;
21 int sta, en;
22
23 int minn1(){
24 int k = -1;
25 int Min = M;
26 for(int i = 0; i < n; i++){
27 if(vis1[i] == 0 && dist1[i] < Min){
28 Min = dist1[i];
29 k = i;
30 }
31 }
32 return k;
33 }
34
35 void dijkstra1(){ //计算最短距离 若有相同则选择途经的点最少的
36 memset(num, 0, sizeof(num));
37 memset(vis1, 0, sizeof(vis1));
38 for(int i = 0; i < n; i++) pre1[i] = sta;
39 for(int i = 0; i < n; i++) dist1[i] = mat1[sta][i];
40 dist1[sta] = 0;
41 pre1[sta] = -1;
42 num[sta] = 1;
43 for(int i = 1; i <= n; i++){
44 int k = minn1();
45 if(k == -1) break;
46 vis1[k] = 1;
47 for(int j = 0; j < n; j++){
48 if(vis1[j] == 0 && dist1[k] + mat1[k][j] < dist1[j]){
49 dist1[j] = dist1[k] + mat1[k][j];
50 pre1[j] = k;
51 num[j] = num[k] + 1;
52 }else if(vis1[j] == 0 && dist1[k] + mat1[k][j] == dist1[j]){
53 if(num[j] > num[k] + 1){
54 num[j] = num[k] + 1;
55 pre1[j] = k;
56 }
57 }
58 }
59 }
60 min_dist = dist1[en];
61 }
62
63 int minn2(){
64 int k = -1;
65 int Min = M;
66 for(int i = 0; i < n; i++){
67 if(vis2[i] == 0 && dist2[i] < Min){
68 Min = dist2[i];
69 k = i;
70 }
71 }
72 return k;
73 }
74
75 void dijkstra2(){ //计算最少时间 若有最少时间相同 则选择最短距离
76 memset(vis2, 0, sizeof(vis2));
77 for(int i = 0; i < n; i++) pre2[i] = sta; //因为sta会最先被选中
78 for(int i = 0; i < n; i++) dist2[i] = mat2[sta][i];
79 dist2[sta] = 0;
80 pre2[sta] = -1;
81 for(int i = 1; i < n; i++){
82 int k = minn2();
83 if(k == -1) break;
84 vis2[k] = 1;
85 for(int j = 0; j < n; j++){
86 if(vis2[j] == 0 && dist2[k] + mat2[k][j] < dist2[j]){
87 dist2[j] = dist2[k] + mat2[k][j];
88 pre2[j] = k;
89 }else if(vis2[j] == 0 && dist2[k] + mat2[k][j] == dist2[j]){
90 if(mat1[pre2[j]][j] > mat1[k][j]){
91 pre2[j] = k;
92 }
93 }
94 }
95 }
96 min_time = dist2[en];
97 }
98
99 void way(int *pre, int x){
100 if(pre[x] == -1){
101 printf("%d", x);
102 return;
103 }else{
104 way(pre, pre[x]);
105 printf(" => %d", x);
106 }
107 }
108
109 int main(){
110 scanf("%d%d", &n, &m);
111 memset(mat1, M, sizeof(mat1));
112 memset(mat2, M, sizeof(mat2));
113 for(int i = 1; i <= m; i++){
114 int a, b, c;
115 scanf("%d%d%d", &a, &b, &c);
116 if(c == 1){
117 scanf("%d%d", &mat1[a][b], &mat2[a][b]);
118 }else{
119 scanf("%d%d", &mat1[a][b], &mat2[a][b]);
120 mat1[b][a] = mat1[a][b]; mat2[b][a] = mat2[a][b];
121 }
122 }
123 scanf("%d%d", &sta, &en);
124 min_dist = M; min_time = M;
125 dijkstra1();
126 dijkstra2();
127 //如果路径统一则合并输出
128 int flag = 1;
129 int temp = en;
130 while(true){
131 if(temp == -1) break; //一定是在相等的基础上的-1
132 if(pre1[temp] == pre2[temp]) temp = pre1[temp];
133 else{
134 flag = 0;
135 break;
136 }
137 }
138 if(flag == 1){
139 printf("Time = %d; Distance = %d: ", min_time, min_dist);
140 way(pre1, en);
141 printf("\n");
142 }else{
143 printf("Time = %d: ", min_time);
144 way(pre2, en);
145 printf("\n");
146 printf("Distance = %d: ", min_dist);
147 way(pre1, en);
148 printf("\n");
149 }
150 return 0;
151 }

天梯赛练习 L3-007 天梯地图 (30分) Dijkstra的更多相关文章

  1. PAT 天梯赛 是否完全二叉搜索树   (30分)(二叉搜索树 数组)

    将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果. 输入格式: 输入第一行给出一个不超过20的正整数 ...

  2. PAT天梯赛练习 L3-003 社交集群 (30分) DFS搜索

    题目分析: 一共有N个编号为1~1000的人,以及一共有编号为1~1000种不同的兴趣,在题目给出1~N编号的人员每个人喜欢的兴趣的id后,要求统计出不同的人员集合的个数以及每个人员几个的人数从大到小 ...

  3. L3-007 天梯地图 (30 分) dijkstra

    本题要求你实现一个天梯赛专属在线地图,队员输入自己学校所在地和赛场地点后,该地图应该推荐两条路线:一条是最快到达路线:一条是最短距离的路线.题目保证对任意的查询请求,地图上都至少存在一条可达路线. 输 ...

  4. 天梯赛练习 L3-011 直捣黄龙 (30分) dijkstra + dfs

    题目分析: 本题我有两种思路,一种是只依靠dijkstra算法,在dijkstra部分直接判断所有的情况,以局部最优解得到全局最优解,另一种是dijkstra + dfs,先计算出最短距离以及每个点的 ...

  5. L3-007 天梯地图 (30分) 最短路+dp

    最短路+dp思路:nuoyanli 520 Let's play computer game 输入样例1: 10 15 0 1 0 1 1 8 0 0 1 1 4 8 1 1 1 5 4 0 2 3 ...

  6. pat天梯赛练习集合 L3-007 天梯地图

    加了一些花的最短路,点的个数为500不需要堆优化,改一下dij的判断条件就可以了. 上代码: #include <iostream> #include <cstring> #i ...

  7. 团体程序设计天梯赛-练习集 L2-001 紧急救援 (25 分)

    作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上.当其他城市有紧急求 ...

  8. PAT天梯赛L3-007 天梯地图

    题目链接:点击打开链接 本题要求你实现一个天梯赛专属在线地图,队员输入自己学校所在地和赛场地点后,该地图应该推荐两条路线:一条是最快到达路线:一条是最短距离的路线.题目保证对任意的查询请求,地图上都至 ...

  9. pat 团体天梯赛 L3-007. 天梯地图

    L3-007. 天梯地图 时间限制 300 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 本题要求你实现一个天梯赛专属在线地图,队员输入自己学校 ...

随机推荐

  1. 自定义radio、checkbox的样式

    input标签中的radio和checkbox是很表单中常用的类型,大多时候,默认样式并不能满足我们的需求,所以有了此篇. 自定义样式,由此开启: html: <div class=" ...

  2. [Python] 快速爬取当前城市所有租房网站房源及配置,一目了然

    Python爬取当前城市房源信息,以徐州为例代码效果图请看下方,其他部分请查看附件,一起学习,谢谢 # -*- coding: utf-8 -*- """ @Time : ...

  3. Spring Boot 的2020最后一击:2.4.1、2.3.7、2.2.12 发布

    近日,Spring Boot官方发布了本年度最后一次版本更新,主要针对目前维护的三个版本: 2.4.x:第一个bug修复版本 2.4.1 2.3.x:常规维护版本 2.3.7 2.2.x:常规维护版本 ...

  4. css进阶 06-CSS开发积累

    06-CSS开发积累 #让flex盒子中的子元素们,居中 flex布局常用的三行代码: display: flex; justify-content: center; // 子元素在横轴的对齐方式 ( ...

  5. PHPCMS V9.6.0 SQL注入漏洞分析

    0x01 此SQL注入漏洞与metinfo v6.2.0版本以下SQL盲注漏洞个人认为较为相似.且较为有趣,故在此分析并附上exp. 0x02 首先复现漏洞,环境为: PHP:5.4.45 + Apa ...

  6. 安装篇五:安装MySQL(5.6.38版本)

    #1.MySQL安装 #1.准备环境 # No1:关闭:(iptables)selinux # No2:下载好安装包(这里使用 mysql-5.6.38.tar.gz 包安装) # No3:安装依赖包 ...

  7. [EF] - Entity Framework 6处理User Defined Function(UDF SQL Server)

    随着EF5的发布,新增了对数据库(SQL Server) UDF的支持,具体可以看以下的连接:https://msdn.microsoft.com/en-us/data/hh859577.aspx,新 ...

  8. 如何使用iis发布多个ftp,为何ftp 503错误?

    使用iis做网站时,需要每个网站都是80端口,所以用到了域名,为了方便发布应用,故将所有网站均添加了ftp发布,当我添加ftp域名绑定后,发现根本无法登陆ftp服务器,后经过百度+博客发现,解决方案: ...

  9. ADF 第八篇:传递参数(Pipeline的Parameter和Variable,Activity的output)和应用表达式

    Azure Data Factory传递参数的方式主要有两种,通过Pipeline的Parameter和Variable来传递参数,通过Activity的输出来传递参数.要在Activity中引用Pa ...

  10. RocketMQ(九):主从同步的实现

    分布式系统的三大理论CAP就不说了,但是作为分布式消息系统的rocketmq, 主从功能是最最基础的了.也许该功能现在已经不是很常用了,但是对于我们理解一些分布式系统的常用工作原理还是有些积极意义的. ...