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& ...
随机推荐
- JAVA中的枚举使用总结
概念 在某些情况下,一个类的对象时有限且固定的,如季节类,它只有春夏秋冬4个对象这种实例有限且固定的类,在 Java 中被称为枚举类; 理解 类里面定义了固定数量的实例,类名如同命令空间 代码 pac ...
- 10 个深恶痛绝的 Java 异常
异常是 Java 程序中经常遇到的问题,我想每一个 Java 程序员都讨厌异常,一 个异常就是一个 BUG,就要花很多时间来定位异常问题. 今天,来列一下 Java 中经常遇到的前 10 个异常,排名 ...
- c 结构体中存在指针,指针的不同赋值方法
#include<stdio.h>#include<stdlib.h>#include<string.h>struct parameter{ char *fd; i ...
- 关于有时候Servlet会被执行两次的问题
用<a>标签做了下载跳转,为什么点一次,servlet会被执行两次? 写了一个最简单的文件下载 点击超链接向servlet发送一个请求,然后下载该文件.可是每次该servlet都会被访问两 ...
- spring3: 4.4 使用路径通配符加载Resource
4.4.1 使用路径通配符加载Resource 前面介绍的资源路径都是非常简单的一个路径匹配一个资源,Spring还提供了一种更强大的Ant模式通配符匹配,从能一个路径匹配一批资源. Ant路径通配 ...
- Learining TypeScript (一) TypeScript 简介
Learining TypeScript (一) TypeScript 简介 一.TypeScript出现的背景 2 二.TypeScript的架构 2 1. 设计目标 2 2 ...
- wireshark捕获到的TCP包图示
wireshark抓到的包与对应的协议层如下图所示: wireshark捕获到的TCP包中的每个字段如下图所示:
- Oracle DBLink连接数过多的问题(Ora-02020)
前不久开发人员编译存储时报ORA -02020 错,如下是解决方案步骤. 报错全信息: Error:OR A -04052在查: 找远程对象 NIP.PB_PERADDRESSLIST@DB_NI ...
- ycsb两个阶段说明
ycsb有几个目录需要注意下: bin: - 目录下有个可执行的ycsb文件,是个python脚本,是用户操作的命令行接口.ycsb主逻辑是:解析命令行.设置java环境,加载java-libs,封 ...
- phpcms内容限制(转发自王小明爱红领巾)
因为页面显示需要对文章内容做剪切,所以用到{str_cut($r[content],60)},但是出现了乱码 所以 {str_cut(strip_tags($r[content]),60)}加stri ...