1131 Subway Map
题意:给出起点和终点,计算求出最短路径(最短路径即所经过的站点最少的),若最短路径不唯一,则选择其中换乘次数最少的一条线路。
思路:本题虽然也是求最短路径,但是此路径是不带权值的,路径长度即所经过的边数,故可以用DFS来求解,而不是用一般的Dijkstra之类的。相信若只是求最短路径,大多数人都会做,就是从起点start开始深度遍历,遍历到终点end时,与全局变量进行比较、更新。本题的关键是,更新最优路径时需要比较“换乘次数”,如何求解它呢?我是这么思考的——首先,考虑用一个二维数组int mp[maxn][maxn]来存储站点与线路的关系,如mp[6666][8432]=4,表示6666->8432是4号线,但考虑到站点编号的范围最大达到9999,也就是数组得开10000*10000,这显然是无法承受的,故选用unordered_map,令unordered_map<int,unordered_map<int,int>> mp,操作和普通的数组一样。(我发现这个unordered_map真的是非常好用,很多题目都可以用,这里不细说,有兴趣的查看文档进行学习)。那么,怎么算是“换乘”呢?假设前一个站是pre,当前站是curr,下一个站是next,若mp[pre][curr]≠mp[curr][next],说明需要一次换乘,顺序遍历路径path的所有站点,即可求出换乘次数。最后,本题的输出也是比较麻烦,但思路和求换乘次数的方法是一样的。具体请看代码,关键处都有注释。
ps.代码中尽量不要出现中文注释,因为在中文输入法下,若不小心在某一行开头输入了一个空格(难以发现),这会导致编译出错,产生“error: stray '\241' in program”的错误信息。
代码:
#include <cstdio>
#include <cstring>
#include <vector>
#include <unordered_map>
using namespace std;
;
const int Inf=0x7fffffff;
unordered_map<int,unordered_map<int,int>> mp;//存储两站点间的地铁线,如mp[6666][8432]=4,表示6666->8432是4号线
bool vis[maxn];//在DFS中标记结点是否已经被访问过
vector<int> graph[maxn];//邻接表存储地铁线路图
int k,n,m,s,e,minDistance,minTransfer;//地铁线条数,每条地铁的站点数,查询次数,查询的起点和终点,最短距离,最少换乘数
vector<int> path,tmpPath;//path存放最优路径,tmpPath存放临时路径
int getTransferCnt(vector<int>& path)
{
;
];
;i+<path.size();i++){//注意,这里的判定是i+1<path.size()
];
if(mp[pre][curr]!=mp[curr][next]) changeCnt++;
pre=curr;//记得更新
}
return changeCnt;
}
void dfs(int s)
{
vis[s]=true;
tmpPath.push_back(s);
if(s==e){
int tmpTransfer=getTransferCnt(tmpPath);
< minDistance){
minDistance=tmpPath.size()-;
minTransfer=tmpTransfer;
path=tmpPath;
} == minDistance && tmpTransfer < minTransfer){
minTransfer=tmpTransfer;
path=tmpPath;
}
return;
}
for(auto next:graph[s]){
if(vis[next] == true) continue;
dfs(next);
tmpPath.pop_back();
vis[next]=false;
}
}
void printPath(vector<int>& path)
{
//换乘次数为0时,只需要输出起点和终点,单独输出。这里minTransfer是全局变量,在调用该函数前已经确定
){
],b=path[path.size()-];//also b=path.back();
printf(]][path[]],a,b);//注意,这里线路不能是mp[a][b],因为站点a、b不一定是相邻的!
return;
}
];//表示当前这条线路的起始站
],curr,next;
;i+<path.size();i++){
curr=path[i],next=path[i+];
if(mp[pre][curr]!=mp[curr][next]) {
printf("Take Line#%d from %04d to %04d.\n",mp[pre][curr],start,curr);
start=curr;//出现换乘,记得更新起始站
}
pre=curr;
}
//输出最后一次换乘至终点的线路
printf(]][path[path.size()-]],start,path[path.size()-]);
}
int main()
{
//freopen("pat.txt","r",stdin);
scanf("%d",&k);
;i<=k;i++){
int pre,curr;
scanf("%d%d",&n,&pre);
;j<n;j++){
scanf("%d",&curr);
graph[pre].push_back(curr);
graph[curr].push_back(pre);
mp[pre][curr]=mp[curr][pre]=i;
pre=curr;
}
}
scanf("%d",&m);
while(m--){
scanf("%d%d",&s,&e);
//每次查询前千万记得初始化
memset(vis,false,sizeof(vis));
path.clear();
tmpPath.clear();
minDistance=Inf,minTransfer=Inf;
dfs(s);
printf("%d\n",minDistance);
printPath(path);
}
;
}
1131 Subway Map的更多相关文章
- PAT甲级1131. Subway Map
PAT甲级1131. Subway Map 题意: 在大城市,地铁系统对访客总是看起来很复杂.给你一些感觉,下图显示了北京地铁的地图.现在你应该帮助人们掌握你的电脑技能!鉴于您的用户的起始位置,您的任 ...
- PAT甲级——1131 Subway Map (30 分)
可以转到我的CSDN查看同样的文章https://blog.csdn.net/weixin_44385565/article/details/89003683 1131 Subway Map (30 ...
- 1131 Subway Map DFS解法 BFS回溯!
In the big cities, the subway systems always look so complex to the visitors. To give you some sense ...
- 1131 Subway Map(30 分)
In the big cities, the subway systems always look so complex to the visitors. To give you some sense ...
- PAT 1131 Subway Map
In the big cities, the subway systems always look so complex to the visitors. To give you some sense ...
- PAT甲级1131 Subway Map【dfs】【输出方案】
题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805347523346432 题意: 告诉你一个地铁线路图,站点都是 ...
- PAT 1131. Subway Map (30)
最短路. 记录一下到某个点,最后是哪辆车乘到的最短距离.换乘次数以及从哪个位置推过来的,可以开$map$记录一下. #include<map> #include<set> #i ...
- PAT_A1131#Subway Map
Source: PAT A1131 Subway Map (30 分) Description: In the big cities, the subway systems always look s ...
- 1131(★、※)Subway Map
思路:DFS遍历 #include <iostream> #include <map> #include <vector> #include <cstdio& ...
随机推荐
- scala学习手记9 - =和==
= 赋值运算 scala的赋值运算和java的有着很大的不同.如a=b这样的赋值运算,在Java中返回值是a的值,在scala中返回的则是Unit(Unit是值类型,全局只存在唯一的值,即(),通常U ...
- MySQL 入门篇
历史 MySQL 是由 David Axmark.Allan Larsson 和 Michael Widenius 3 个瑞典人于 20 世纪 90 年代开发的一个关系型数据库.MySQL 之名取自创 ...
- Ajax-04 jQuery Ajax 常用操作
jQuery jQuery 其实就是一个JavaScript的类库,其将复杂的功能做了上层封装,使得开发者可以在其基础上写更少的代码实现更多的功能. jQuery Ajax a.概述 jQuery 不 ...
- 【machine learning通俗讲解code逐行注释】之线性回归实现
现在机器学习算法在分类.回归.数据挖掘等问题上运用的十分广泛,对于初学者来说,可能一听到'算法'或其他的专属名词都感觉高深莫测,以致很多人望而却步,这让很多人在处理很多问题上失去了一个很有用的工具.机 ...
- 【2018年全国多校算法寒假训练营练习比赛(第五场)-E】情人节的电灯泡(二维树状数组单点更新+区间查询)
试题链接:https://www.nowcoder.com/acm/contest/77/E 题目描述 情人节到了,小芳和小明手牵手,打算过一个完美的情人节,但是小刚偏偏也来了,当了一个明晃晃的电灯泡 ...
- java String 转 Long 两种方法区别
Long.ValueOf("String")返回Long包装类型 包装类型: Byte,Integer,Short,Long,Boolean,Character,Float,Dou ...
- [Scala]Scala学习笔记二 数组
1. 定长数组 如果你需要一个长度不变的数组,可以使用Scala中的Array. val nums = new Array[Int](10) // 10个整数的数组 所有元素初始化为0 val str ...
- Ubuntu下搭建WordPress环境
WordPress是一种使用PHP语言开发的博客平台,用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站.也可以把 WordPress当作一个内容管理系统(CMS)来使用.WordPr ...
- 在C / C ++中清除输入缓冲区
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解 ...
- Beego的controller怎么用嵌入实现继承问题
Go Lang是无继承层次的轻量级面向对象编程范式.Go Lang中的接口与实现之间完全是非侵入式的.这种接口实现方式很值得称赞.不但如此,在Go Lang中只有类型嵌入而没有类型继承.这规避了很多与 ...