题意:

TT 从家里出发,准备乘坐猫猫快线前往喵星机场。猫猫快线分为经济线和商业线两种,它们的速度与价钱都不同。当然啦,商业线要比经济线贵,TT 平常只能坐经济线,但是今天 TT 的魔法猫变出了一张商业线车票,可以坐一站商业线。假设 TT 换乘的时间忽略不计,请你帮 TT 找到一条去喵星机场最快的线路,不然就要误机了!
输入包含多组数据。每组数据第一行为 3 个整数 N, S 和 E (2 ≤ N ≤ 500, 1 ≤ S, E ≤ 100),即猫猫快线中的车站总数,起点和终点(即喵星机场所在站)编号。
下一行包含一个整数 M (1 ≤ M ≤ 1000),即经济线的路段条数。
接下来有 M 行,每行 3 个整数 X, Y, Z (1 ≤ X, Y ≤ N, 1 ≤ Z ≤ 100),表示 TT 可以乘坐经济线在车站 X 和车站 Y 之间往返,其中单程需要 Z 分钟。
下一行为商业线的路段条数 K (1 ≤ K ≤ 1000)。
接下来 K 行是商业线路段的描述,格式同经济线。
所有路段都是双向的,但有可能必须使用商业车票才能到达机场。保证最优解唯一。
对于每组数据,输出3行。第一行按访问顺序给出 TT 经过的各个车站(包括起点和终点),第二行是 TT 换乘商业线的车站编号(如果没有使用商业线车票,输出"Ticket Not Used",不含引号),第三行是 TT 前往喵星机场花费的总时间。
本题不忽略多余的空格和制表符,且每一组答案间要输出一个换行。


思路:

题目给定了起点与终点,而且要求商业线最多乘坐一次。可以枚举每一条商业线(u,v),计算起点s到u的最短路以及v到终点e的最短路再加上该商业线所花费的时间,然后取最短时间与不走商业线的时间进行比较,取较小值。
用dijkstra来实现:以起点s为源点求最短路,得到dis1数组,再以终点e为源点求最短路,得到dis2数组。枚举商业线(u,v,w),取min{dis1[u]+dis2[v]+w,dis1[v]+dis2[u]+w},最终再与不走商业线的答案取min。
存经济线使用了链式前向星,防止用邻接矩阵导致TE。而商业线只需要存储u,v,w即可,所以用了边来存储。
dijkstra:很正常的dijkstra,唯一不同就是要用pre数组来存储每个点的上一个顶点,用于输出时回溯路径。
经过两次dijkstra求最短路后,要枚举商业线求最小时间,此时用syU和syV来表示最小时间对应的商业线顶点。枚举完商业线后要进行输出。输出分为从后往前输出(从syU到起点s)和从前往后输出(从syV到终点e),前者使用了递归回溯路径实现输出,后者遍历pre数组完成输出。


总结:

一道两遍dijkstra的题目,很容易T,还卡输出格式,还多组数据。交了19发才A了。
代码修改的地方:读入由cin(没关流同步)到scanf(但改完还是T了);链式前向星存经济线的数组由1100开到了2100(一开始开小了,1000的边存两次是2000,1100是不够的,但开小了是TE而不是RE就想不通为什么,这个地方调了好久);枚举商业线的地方又换了一种写法(但还是不知道前一种写法哪里错了);最后PE又改了输出格式,最后一组数据不用再输出空行。
其实还有思路二:跑一次dijkstra变形,记录答案dis[u][0/1],其中dis[u][0]表示从起点到终点u没有经过商业线时的最短路,在松弛的时候可以选择商业线或者经济线;dis[u][1]表示从起点到终点u经过商业线后的最短路,在松弛的时候只能选择经济线。
一开始觉得思路二只需要改一改dijkstra就能写完,感觉很简单就先写的思路二。结果调了好久还是T,就转为思路一了,而思路一也是写了好长时间才搞定。看看其他大佬交了一两发就A了,看来自己写代码的路还很长啊。


代码:

#include <iostream>
#include <stdio.h>
#include <queue>
#include <stack>
using namespace std;int MAX_G=1e8;
int n,s,e,m,k;
//链式前向星
struct edge
{int to,next,w;
};
edge ed[2100];
int head[600],tot;
void add(int x,int y,int w)
{ed[++tot].to=y,ed[tot].next=head[x];ed[tot].w=w,head[x]=tot;
}
//边,用于存储商业线
struct shangye
{int u,v,w;
} syEdge[1100];
int dis1[600],dis2[600];    //距离起点和终点的距离
int pre1[600],pre2[600];
bool vis1[600],vis2[600];
struct point    //记录顶点v到源点的距离
{int v,juli;point(int v1,int juli1){v=v1,juli=juli1;}
};
struct cmp
{bool operator () (point a,point b){return a.juli>b.juli;}
};
priority_queue<point,vector<point>,cmp> q;
void dijkstra(int source,int dis[],int pre[],bool vis[])
{while(!q.empty())q.pop();dis[source]=0;point thePoint(source,0);q.push(thePoint);while(!q.empty()){int x=q.top().v;q.pop();if(vis[x])continue;vis[x]=1;for(int i=head[x]; i!=0; i=ed[i].next)    //经济线{int y=ed[i].to,w=ed[i].w;if(dis[y]>dis[x]+w){dis[y]=dis[x]+w;pre[y]=x;point pp(y,dis[y]);q.push(pp);}}}
}
void output1(int v) //从后往前输出
{if(v!=s)output1(pre1[v]);if(v==s)printf("%d",v);elseprintf(" %d",v);
}
void output2(int v) //从前往后输出
{while(v!=e){printf(" %d",v);v=pre2[v];}printf(" %d",v);
}
int main()
{int sjzs=0;   //数据组数while(~scanf("%d%d%d",&n,&s,&e)){//清空表for(int i=0; i<600; i++)head[i]=0,dis1[i]=MAX_G,dis2[i]=MAX_G,pre1[i]=0,pre2[i]=0,vis1[i]=0,vis2[i]=0;tot=0;scanf("%d",&m);//读入for(int i=0; i<m; i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);add(x,y,z);add(y,x,z);}scanf("%d",&k);for(int i=1; i<=k; i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);syEdge[i].u=x,syEdge[i].v=y,syEdge[i].w=z;}dijkstra(s,dis1,pre1,vis1);dijkstra(e,dis2,pre2,vis2);sjzs++;if(sjzs>1)   cout<<endl;int minAns=MAX_G;int syU,syV; //syU连接起点s,syV连接终点e for(int i=1; i<=k; i++){int u=syEdge[i].u,v=syEdge[i].v,w=syEdge[i].w;if(minAns>min(dis1[u]+dis2[v]+w,dis1[v]+dis2[u]+w)){if(dis1[u]+dis2[v]+w<dis2[u]+dis1[v]+w){minAns=dis1[u]+dis2[v]+w;syU=u,syV=v;}else{minAns=dis1[v]+dis2[u]+w;syU=v,syV=u;}}}if(minAns>dis1[e])    //经济线{minAns=dis1[e];output1(e);printf("\n");printf("Ticket Not Used\n");printf("%d\n",minAns);}else //含商业线syU,syV{output1(syU);output2(syV);printf("\n");printf("%d\n",syU);printf("%d\n",minAns);}}
}

【Week7作业 B】TT的旅行日记【dijkstra】相关推荐

  1. SDU 程序设计思维与实践 week7 B TT 的旅行日记【Dijkstra】

    B TT 的旅行日记 题意描述 众所周知,TT 有一只魔法猫 今天他在 B 站上开启了一次旅行直播,记录他与魔法猫在喵星旅游时的奇遇. TT 从家里出发,准备乘坐猫猫快线前往喵星机场.猫猫快线分为经济 ...

  2. 算法-程序设计课week7-作业-B - TT 的旅行日记

    文章目录 题目 思路 路径输出 总的步骤 心得 代码 题目 众所周知,TT 有一只魔法猫. 今天他在 B 站上开启了一次旅行直播,记录他与魔法猫在喵星旅游时的奇遇. TT 从家里出发,准备乘坐猫猫快线 ...

  3. 【20200401程序设计思维与实践 Week7作业】

    目录 A - TT 的魔法猫 题意 思路 总结 代码 B - TT 的旅行日记 题意 思路 总结 代码 C - TT 的美梦 题意 思路 总结 代码 A - TT 的魔法猫 题意 众所周知,TT 有一 ...

  4. 微信小程序实战 《跨时空》旅行日记小程序

    题外话 我喜欢旅行,在正文开始前,先向有共同兴趣的朋友推荐一个自己每次出行前必装的 APP -- 面包旅行.我主要用它来写旅行日志,每天行程结束,我都会将当天拍的照片上传并做简单的文字记录,记录是回顾 ...

  5. 马卡龙色系旅行日记PPT模板-优页文档

    模板介绍 马卡龙色系旅行日记PPT模板-优页文档.一套,生活旅游,个人相册,幻灯片模板,内含青色,黄色多种配色,风格设计,动态播放效果,精美实用. 希望下面这份精美的PPT模板能给你带来帮助,温馨提示 ...

  6. 甜酷女孩叶悠悠,邀你走进她的元宇宙旅行日记

    创世藏品 叶悠悠元宇宙旅行日记 醉美中国系列数字藏品 12月16日上午10点 百度APP[星际口袋]小程序限量发售! 她是谁? 叶悠悠是百度输入法首创推出的两位情感陪伴型虚拟博主之一,这位27岁的人间 ...

  7. HDU2066:一个人的旅行(Dijkstra)

    Problem Description 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,0),很多事,还能丰富自 ...

  8. B.一个人的旅行 (dijkstra算法)

    这题实在太醉了.十分简单的一道最短路径.我也wa了几次.最后发现可能是在循环次数n的设置上溢出了.s[1001]最大就1000...注意两点之间不止一个路径.上一题畅通工程就被坑惨了. 下面附题目 B ...

  9. 【HDU - 2066】:一个人的旅行(Dijkstra算法)

    题干: 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰富自己的阅历,还可以看美丽的风景 ...

最新文章

  1. PHP实现http与https转化[转张宴]
  2. phpstorm xdebug remote配置
  3. Laravel源码解析之从入口开始
  4. 数据中心架构有哪些组件?
  5. 直播 | ACL 2021论文解读:基于对抗学习的事件抽取预训练模型
  6. ICML 2020 | Google提出最强生成式摘要预训练模型——天马
  7. 软件工程与项目管理的关系_软件工程:软件工程概述13个问题解答?
  8. cisco MST配置
  9. python第三方库安装的各种方法(全网最全,最简单易懂)
  10. 文本检测-EAST方法概述
  11. Java-NIO实战多人聊天室
  12. 因为一个字符校对问题,我的大厂面试挂了
  13. (53)Verilog HDL上升沿采样
  14. php5.4 无法连接mongo,php连接MongoDB总是失败,为什么?
  15. 设计模式C++实现--Factory模式
  16. 2021年9月基因编辑/CRISPR最新研究进展
  17. 目标跟踪笔记Understanding and Diagnosing Visual Tracking Systems
  18. element-ui 表格吸底固定最后一行
  19. ASP是什么?ASP初识
  20. maven中遇到的问题,报错

热门文章

  1. 微积分的需求和基本定理
  2. MySQL 三万字精华总结 + 面试100 问,和面试官扯皮绰绰有余(收藏系列)
  3. Cocos Creator 初探:修改Engine来调整FPS信息显示
  4. Java自我学习第三章基础数据类型
  5. centos7下使用yum安装ifconfig
  6. PubSub Websocket实时通信 - GoEasy在小程序中的使用
  7. 美联致美医学美容面部填充用的什么方法?
  8. IC的ESD测试方法
  9. 如何做微博营销 你知道吗?
  10. Java 封装的详解