浙大PAT CCCC L3-014 周游世界 ( 最短路变形 )
题意 : 中文题请点链接,挺复杂的...
分析 : 乍一看是个最短路,实际就真的是个最短路。如果没有 “ 在有多条最短路径的时候输出换乘次数最少的” 这一条件的约束,那么这题就是直接建图然后跑个 Dij 就行了,那有了这个约束条件还是要大胆的向最短路思路靠,题目既然需要换乘次数少的,那么我们在进行最短路松弛操作的时候,面对松弛过后最短路径相等的情况就要分开讨论,这时候为了方法取最优值,需要多记录一个信息 ==> 跑到当前点时候换乘次数是多少次,开个数组来记录就行了,其他的还是按最短路来跑。这题就是编码烦了点,不对!是非常烦_(:3 」∠)_
#include<bits/stdc++.h> using namespace std; ; ]; ///向前星存图 struct NODE{ ///跑DIJ时塞在优先队列的结构体 int v, Pre_v, TransferCnt, Dist; ///当前是哪个点、其前一个点是什么、换乘次数、源点到此点的最短距离 NODE(int V, int D, int Pv, int TCnt):v(V),Dist(D),Pre_v(Pv),TransferCnt(TCnt){}; bool operator < (const NODE &rhs) const{ if(this->Dist == rhs.Dist){ ///最短距离相等应当选择换乘次数小的 return this->TransferCnt > rhs.TransferCnt; ///由于是优先队列、重载小于号需要注意方向.... }else{ return this->Dist > rhs.Dist; } }; }; int cnt; ///边数量 int Head[maxn]; ///邻接表头 int Pre[maxn]; ///答案路径中每个点的前驱、便于恢复路径 int Dis[maxn]; ///记录Dij中源点到其他点的最短路距离 int TransNum[maxn]; ///到达这个点的时候换乘了多少次 int Line[maxn][maxn]; ///记录路线信息 ]; ///存储答案路径 bool vis[maxn]; ///DIJ中的标记数组 inline void init() ///初始化表头和计数变量 { memset(Head, -, sizeof(Head)); cnt = ; } inline void AddEdge(int from, int to) ///加边函数 { Edge[cnt].v = to; Edge[cnt].nxt = Head[from]; Head[from] = cnt++; } inline void Run_Dijkstra(int st, int en) { memset(vis, false, sizeof(vis)); memset(Dis, 0x3f3f3f3f, sizeof(Dis)); memset(TransNum, , sizeof(TransNum)); priority_queue<NODE> que; while(!que.empty()) que.pop(); Dis[st] = ; que.push(NODE(st,,,)); while(!que.empty()){ NODE T = que.top(); que.pop(); if(vis[T.v]) continue; else vis[T.v] = true; ; i=Edge[i].nxt){ int Eiv = Edge[i].v; ){ ///满足松弛条件 Dis[Eiv] = Dis[T.v] + ; : T.TransferCnt + (Line[T.v][Eiv] != Line[T.Pre_v][T.v])); ///计算新的换乘次数 que.push(NODE(Eiv, Dis[Eiv], T.v, NewTrans)); Pre[Eiv] = T.v; ///记录前驱、便于恢复路径 TransNum[Eiv] = NewTrans; ///记录当前点的换乘次数 } && ///最短距离与松弛后相等则接下来比较换乘次数 TransNum[Eiv] > T.TransferCnt + (Line[T.v][Eiv] != Line[T.Pre_v][T.v])){ que.push(NODE(Eiv, Dis[Eiv], T.v, T.TransferCnt + (Line[T.v][Eiv] != Line[T.Pre_v][T.v]))); Pre[Eiv] = T.v; ///改变前驱 TransNum[Eiv] = T.TransferCnt + (Line[T.v][Eiv] != Line[T.Pre_v][T.v]); ///更新换乘次数 } } } if(Dis[en] == 0x3f3f3f3f){ ///不可达、输出 No Solution puts("Sorry, no line is available."); return ; }else{ ; ///记录路径中节点个数 int now = en; ///由于记录的是前驱、所以从终点开始恢复路径 int StNext; path[top++] = en; while(now != st){ int temp = Pre[now]; if(temp==st) StNext = now; ///记录起点的后继 ==> 我接下来的输出满足题目所需的答案有需要 path[top++] = temp; now = temp; } printf("%d\n", Dis[en]); ///先输出最短距离 int CurLine = Line[st][StNext]; ///从起点开始记录当前所在的铁路编号 int CurPoint = st; ///当前的点 ; i>=; i--){ ]] == CurLine) continue; ///如果下一个点和仍然在和之前一样的铁路编号则说明不是换乘点 else{ printf("Go by the line of company #%d from %04d to %04d.\n",CurLine, CurPoint, path[i]); ///输出格式需要注意.... ///printf("Go by the line of company #%d from %d to %d.\n", CurLine, CurPoint, path[i]); ///!!!错误的输出格式!!! CurPoint = path[i]; ///更新 CurPoint、CurLine CurLine = Line[path[i]][path[i-]]; } } printf(]); ///printf("Go by the line of company #%d from %d to %d.\n", CurLine, CurPoint, path[0]); ///!!!错误的输出格式!!! } } int main(void) { init(); int n; scanf("%d", &n); ; i<=n; i++){ int num, A, B; scanf("%d %d", &num, &A); ; j<num; j++){ scanf("%d", &B); AddEdge(A, B); AddEdge(B, A); Line[A][B] = Line[B][A] = i; A = B; } } int Query; scanf("%d", &Query); while(Query--){ int A, B; scanf("%d %d", &A, &B); Run_Dijkstra(A, B); } ; }
浙大PAT CCCC L3-014 周游世界 ( 最短路变形 )的更多相关文章
- 浙大PAT CCCC L3-001 凑零钱 ( 0/1背包 && 路径记录 )
题目链接 分析 : 就是一个 0/1 背包,但是需要记录具体状态的转移情况 这个可以想象成一个状态转移图,然后实际就是记录路径 将状态看成点然后转移看成边,最后输出字典序最小的路径 这里有一个很巧妙的 ...
- 浙大PAT CCCC L3-013 非常弹的球 ( 高中物理题 )
题目链接 题意 : 刚上高一的森森为了学好物理,买了一个“非常弹”的球.虽然说是非常弹的球,其实也就是一般的弹力球而已.森森玩了一会儿弹力球后突然想到,假如他在地上用力弹球,球最远能弹到多远去呢?他不 ...
- 浙大PAT CCCC L3-015 球队“食物链” ( 搜索 && 剪枝 )
题目链接 题意 : 有 n 个球队,给出主客场胜负图,找出一个序列 1.2.3..... 使得 1 战胜过 2 .2 战胜过 3.3 战胜过 4..... n 战胜过 1 ( 这个序列是 1~n 的其 ...
- 天梯赛 大区赛 L3-014.周游世界 (Dijkstra)
L3-014. 周游世界 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 周游世界是件浪漫事,但规划旅行路线就不一定了-- 全世 ...
- L3-014 周游世界 (30 分)
周游世界是件浪漫事,但规划旅行路线就不一定了…… 全世界有成千上万条航线.铁路线.大巴线,令人眼花缭乱.所以旅行社会选择部分运输公司组成联盟,每家公司提供一条线路,然后帮助客户规划由联盟内企业支持的旅 ...
- 团体程序设计天梯赛(CCCC) L3014 周游世界 BFS证明
团体程序设计天梯赛代码.体现代码技巧,比赛技巧. https://github.com/congmingyige/cccc_code
- A题进行时--浙大PAT 1001-1010
pat链接:http://pat.zju.edu.cn 1 #include<stdio.h> 2 int main(){ 3 int a,b; 4 int c; 5 while(scan ...
- 浙大pat 1035题解
1035. Password (20) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue To prepare f ...
- 浙大pat 1025题解
1025. PAT Ranking (25) 时间限制 200 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Programmi ...
随机推荐
- 【python+selenium自动化】设置Chrome启动参数
起因:直接用selenium的webdriver启动chrome,会弹出“Chrome正在受到自动软件的控制”,并且窗口较小,是因为chrome没有加载任何配置 解决:点进selenium的Chrom ...
- 【Python】关于近期爬虫学习的总结
写在开头 在之前的三篇文章中,我尝试了使用python爬虫实现的对于特定站点的<剑来>小说的爬取,对于豆瓣的短评的爬取,也有对于爬取的短评数据进行的词云展示,期间运用了不少的知识,现在是时 ...
- redis学习(二)
深入了解redis字符串,列表,散列和有序集合命令,了解发布,订阅命令和其他命令. 一,字符串 1.字符串可以存储3种类型的值 字符串,整数,浮点数 2.运算命令列表 incr : incr ...
- python+selenium切换窗口(获取句柄信息)
current_window_handle:获得当前窗口句柄: window_handles:返回所有窗口的句柄到当前会话: switch_to.window(suoyou[0]) ========= ...
- python 并发编程 多进程 Process对象的其他属性方法 join 方法
一 Process对象的join方法 在主进程运行过程中如果想并发地执行其他的任务,我们可以开启子进程,此时主进程的任务与子进程的任务分两种情况 情况一: 在主进程的任务与子进程的任务彼此独立的情况下 ...
- [DS+Algo] 003 一维表结构 Python 代码实现
接上一篇 前言 本篇共 3 个代码实现 严格来说 code1 相当于模仿了 Python 的 list 的部分简单功能 code2 与 code3 简单实现了"循环单链表"与&qu ...
- vue组件化编程应用
写几个小案例来理解vue的组件化编程思想,下面是一个demo. 效果图示: 功能: Add组件用于添加用户评论,提交后右边评论回复会立马显示数据.Item组件点击删除可以删除当前用户评论.当List组 ...
- c++多线程并发学习笔记(0)
多进程并发:将应用程序分为多个独立的进程,它们在同一时刻运行.如图所示,独立的进程可以通过进程间常规的通信渠道传递讯息(信号.套接字..文件.管道等等). 优点:1.操作系统在进程间提供附附加的保护操 ...
- 8. golang 基本类型转换
golang 类型转换只能显性转换 不能自动转换 基本数据类型间的转换 var x1 int = 2 var x2 int16 var x3 int8 x2 = 200 + x1 x3 = 200 + ...
- HNUSTOJ-1690 千纸鹤
1690: 千纸鹤 时间限制: 1 Sec 内存限制: 128 MB提交: 992 解决: 296[提交][状态][讨论版] 题目描述 圣诞节快到了,校园里到处弥漫着粉红色的气息.又是一个情侣秀 ...