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

思路:本题虽然也是求最短路径,但是此路径是不带权值的,路径长度即所经过的边数,故可以用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. Samba的安装配置使用

    ////////////////////////////////Samba//////////////////////////////////////////// 小常识:在同一局域网中,两个系统的工 ...

  2. datetimepicker

    <!DOCTYPE html> <html> <head> <title></title> <link href="./bo ...

  3. # IFE前端(2015春)-task2

    第一章 JavaScript数据类型及语言基础 期望达成 掌握JavaScript的各种数据类型概念.判断方法 掌握JavaScript函数.对象的概念 掌握字符串.数字.数组.日期等对象的方法 了解 ...

  4. activity启动模式之singleInstance

    activity启动模式之singleInstance 一.简介 Log.d("C2", getTaskId()+"");里面的getTaskId()可以获取a ...

  5. java之字符串中查找字串的常见方法

    1.int indexOf(String str) :返回第一次出现的指定子字符串在此字符串中的索引.      int indexOf(String str, int startIndex):从指定 ...

  6. hdu 5979 Convex(水,求面积)

    Convex Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  7. 对CSS了解-overflow:hidden

    overflow:hidden 列出我在项目中,运用到此属性的例子: (1)暴力清除浮动 <style type="text/css"> .wrap {;backgro ...

  8. Struts08---全局结果和全局异常的配置

    01.创建测试页面 <%-- 验证全局结果 和 局部结果 --%> <a href="user/UserAction_add">新增用户</a> ...

  9. LeetCode OJ:Integer to Roman(转换整数到罗马字符)

    Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 t ...

  10. 关于HashMap,HashTable,HashSet浅析

    首先,最重要的,HashMap  作为一个我们使用非常多的集合.最常被大家认知的是,它是一个key-value形式存储数据的数据结构,可以实现快速的存,取操作.  关于HashMap的源码,我们截取一 ...