浙大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 ...
随机推荐
- 机器学习【一】K最近邻算法
K最近邻算法 KNN 基本原理 离哪个类近,就属于该类 [例如:与下方新元素距离最近的三个点中,2个深色,所以新元素分类为深色] K的含义就是最近邻的个数.在sklearn中,KNN的K值是通过n ...
- Python3 多线程编程 threading模块
性能自动化测试除了用jmeter还可以用python threading模块做 一.threading模块定义 Python 2.4中包含的较新的线程模块为线程提供了更强大的高级支持. 线程模块公开线 ...
- liteide使用中的注意点
liteide使用中的注意点 无法跳转 会出现无法跳转的情况,可能是这个包里面的某个文件会有错误,一般把这个包里的所有的错误都改正之后就能正常跳转了.Ubuntu中,直接按f2可以跳入,之后按住alt ...
- 20191110 Spring Boot官方文档学习(3)
3.使用Spring Boot 3.1.构建系统 建议选择Maven或Gradle作为构建工具 每个Spring Boot版本都提供了它所支持的依赖关系的精选列表.实际上,您不需要为构建配置中的所有这 ...
- realloc ------ 扩大malloc得到的内存空间
char* p = malloc(1024);char* q = realloc(p,2048); 现在的问题是我们应该如何处理指针 p. 刚开始按照我最直观的理解,如果就是直接将 p = NULL; ...
- 使用Oracle12c 以上的PDB创建数据库用户 密码过期的简单处理
1. 先通过监听查看PDB的名字 Windows 打开命令行: 输入命令 lsnrctl status 一般在如图示的最下面 2. 也可以通过GS的全局配置文件来查看 数据库连接SID信息. C:\P ...
- Zend_Cache的使用
一.Zend_Cache快速浏览 Zend_Cache 提供了一个缓存任何数据的一般方法. 在Zend Framework中缓存由前端操作,同时通过后端适配器(File, Sqlite, Memcac ...
- Delphi XE2_XE3 Update
Delphi 和 C++Builder XE2 更新摘要 XE2的关键特性如下: 1. FireMonkey Application Platform支持运行在Windows (32和64位),Mac ...
- eclipse调试openstack的nova代码
前段时间一直在研究openstack的nova部分的代码.特别想知道,怎样用eclipse来调试代码.也在论坛上问了别人.无果.最后还是自己摸索出了出路. 以下写出自己探索之路.我是用devstack ...
- css禁止鼠标双击选中文字
div{ -moz-user-select:none;/*火狐*/ -webkit-user-select:none;/*webkit浏览器*/ -ms-user-select:none;/*IE10 ...