题意:给出起点和终点,计算求出最短路径(最短路径即所经过的站点最少的),若最短路径不唯一,则选择其中换乘次数最少的一条线路。

思路:本题虽然也是求最短路径,但是此路径是不带权值的,路径长度即所经过的边数,故可以用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的更多相关文章

  1. PAT甲级1131. Subway Map

    PAT甲级1131. Subway Map 题意: 在大城市,地铁系统对访客总是看起来很复杂.给你一些感觉,下图显示了北京地铁的地图.现在你应该帮助人们掌握你的电脑技能!鉴于您的用户的起始位置,您的任 ...

  2. PAT甲级——1131 Subway Map (30 分)

    可以转到我的CSDN查看同样的文章https://blog.csdn.net/weixin_44385565/article/details/89003683 1131 Subway Map (30  ...

  3. 1131 Subway Map DFS解法 BFS回溯!

    In the big cities, the subway systems always look so complex to the visitors. To give you some sense ...

  4. 1131 Subway Map(30 分)

    In the big cities, the subway systems always look so complex to the visitors. To give you some sense ...

  5. PAT 1131 Subway Map

    In the big cities, the subway systems always look so complex to the visitors. To give you some sense ...

  6. PAT甲级1131 Subway Map【dfs】【输出方案】

    题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805347523346432 题意: 告诉你一个地铁线路图,站点都是 ...

  7. PAT 1131. Subway Map (30)

    最短路. 记录一下到某个点,最后是哪辆车乘到的最短距离.换乘次数以及从哪个位置推过来的,可以开$map$记录一下. #include<map> #include<set> #i ...

  8. PAT_A1131#Subway Map

    Source: PAT A1131 Subway Map (30 分) Description: In the big cities, the subway systems always look s ...

  9. 1131(★、※)Subway Map

    思路:DFS遍历 #include <iostream> #include <map> #include <vector> #include <cstdio& ...

随机推荐

  1. JDK__下载地址

    1. http://www.oracle.com/technetwork/java/archive-139210.html ZC: 貌似 从JDK7开始,有for ARM的版本,类似 : “Linux ...

  2. WPF 自定义依赖属性

      原博客地址:http://www.cnblogs.com/DebugLZQ/archive/2012/11/30/2796021.html    DependencyObject和Dependen ...

  3. java String转Long两种方法区别

    第一种:包装类型:Byte,Integer,Short,Long,Boolean,Character,Float,Double等8种 Long.valueOf("String")返 ...

  4. vue-cli favicon 怎么引入

    把你的 favicon 图标放到 static 目录下,然后修改 link 标签指向 static 目录下的 favicon 图标文件即可

  5. IOS-CoreLocation

    一.简介 在移动互联网时代,移动app能解决用户的很多生活琐事,比如 导航:去任意陌生的地方 周边:找餐馆.找酒店.找银行.找电影院   在上述应用中,都用到了地图和定位功能,在iOS开发中,要想加入 ...

  6. XML的两种解析方式

    JDK提供的XML解析方式分为两种:DOM方式和SAX方式DOM:Document Object Model.需要读取整个XML文档,先需要在内存中构架代表整个DOM树的Document对象,可以进行 ...

  7. 条款22:将成员变量声明为private

    protected成员变量的封装性并非高于public变量. 如果有个public的成员变量,一旦其需要改变,那么所有使用它的代码都需要改变. 如果有个protected的成员变量,一点其需要改变,那 ...

  8. CSS: The resize Property

    用户手动调节输入框样式: <!DOCTYPE html> <html> <head> <style> div { border: 2px solid; ...

  9. 导出/打印项目数据报表需要设置IE浏览器

    导出/打印项目数据报表需要设置IE浏览器如下: 1.将本地服务器站点设置为可信站点, 2.通过点击网页上的工具→Internet选项→安全→自定义级别→把关于activeX控件和插件的选项都设置成启用 ...

  10. Java并发编程之CountDownLatch

    一.场景描述 在多线程程序设计中,经常会遇到一个线程等待一个或多个线程的场景 例如:百米赛跑,十名运动员同时起跑,由于速度的快慢,肯定有先到达和后到达的,而终点有个统计成绩的仪器,当所有选手到达终点时 ...