当前位置:首页 > 牛客 > 牛客16444题解析:公交线路最短路径算法优化(BFS+双向映射)

牛客16444题解析:公交线路最短路径算法优化(BFS+双向映射)

2周前 (09-05)

牛客16444题解析:公交线路最短路径算法优化(BFS+双向映射) 牛客题解 BFS算法 双向映射 C++实现 广搜 广度优先搜索 最短路径 映射 第1张

一、题目解读

本题要求求解一个公交线路网络中的最短路径问题:给定n个站点和m条公交线路,每条线路包含多个站点,求从起点站1到终点站n的最小换乘次数。题目需高效处理站点与线路的双向关联,并优化路径搜索效率。

二、解题思路

采用双向映射+BFS的解题策略:

1. 构建双向映射:使用station_to_buses(站点→线路)和bus_to_stations(线路→站点)两个数据结构,快速获取某站点可乘坐的公交车及某公交车途经的站点。

2. BFS搜索:从起点1开始,逐层扩展可达站点,每次仅考虑未访问过的公交车,避免重复计算换乘次数。

3. 状态标记:用visited_bus数组记录已访问的公交车,确保每条线路仅被遍历一次,降低时间复杂度。

三、解题步骤

1. 输入与初始化:读取n、m及线路信息,建立双向映射。

2. BFS搜索:

队列初始化:起点站{1, 0}入队,dist[1]=0。

○ 循环直至队列为空:

    出队当前站点和花费cost。

    若到达终点n,输出cost并结束。

    遍历该站可乘坐的所有公交车:

        若公交车未访问,标记visited_bus[bus]=true。

        遍历该公交车途经的所有站点next_station:

○ 更新最小花费dist[next_station] = cost + 1,并入队{next_station, cost + 1}。

3. 输出结果:若未找到路径,输出-1。

四、代码与注释

#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
#include <unordered_set>
using namespace std;

const int INF = 1e9;  // 定义无穷大

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);  // 加速输入输出

    int n, m;  // 站点数n,线路数m
    cin >> n >> m;

    // 双向映射:站点→线路,线路→站点
    unordered_map<int, vector<int>> station_to_buses;
    vector<vector<int>> bus_to_stations(m);
    for (int i = 0; i < m; ++i) {
        int t;  // 当前线路包含的站点数
        cin >> t;
        bus_to_stations[i].resize(t);  // 分配空间
        for (int j = 0; j < t; ++j) {
            cin >> bus_to_stations[i][j];
            station_to_buses[bus_to_stations[i][j]].push_back(i);  // 双向关联
        }
    }

    // BFS队列:存储{站点, 花费}
    queue<pair<int, int>> q;
    q.push({1, 0});  // 起点入队

    // 记录各站点的最小花费(初始化为INF)
    vector<int> dist(n + 1, INF);
    dist[1] = 0;  // 起点花费为0

    // 标记已访问的公交车
    vector<bool> visited_bus(m, false);

    while (!q.empty()) {
        auto [station, cost] = q.front();  // 当前站点和花费
        q.pop();

        if (station == n) {  // 到达终点
            cout << cost << endl;
            return 0;
        }

        // 遍历当前站点可乘坐的所有公交车
        for (int bus : station_to_buses[station]) {
            if (visited_bus[bus]) continue;  // 已访问,跳过
            visited_bus[bus] = true;  // 标记访问

            // 遍历该公交车途经的所有站点
            for (int next_station : bus_to_stations[bus]) {
                if (dist[next_station] > cost + 1) {  // 更新更短路径
                    dist[next_station] = cost + 1;
                    q.push({next_station, cost + 1});
                }
            }
        }
    }

    // 未找到路径
    cout << -1 << endl;
    return 0;
}

五、总结

本题核心在于利用双向映射高效处理站点与线路的关联关系,结合BFS搜索实现最短路径查找。通过标记已访问公交车,避免重复遍历线路,显著优化时间复杂度。算法实现简洁高效,适用于大规模公交网络路径规划问题。


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣501题最优解:不用额外空间找出BST中的众数?这个解法让你大开眼界

力扣501题最优解:不用额外空间找出BST中的众数?这个解法让你大开眼界

题目解读‌:在二叉搜索树的世界里,每个节点都默默记录着自己的数值。现在我们需要找出这些数值中出现频率最高的那些数字,也就是所谓的"众数"。有趣的是,二叉搜索树本身具有左小右大的特性...

洛谷P2346四子连珠游戏最短步数BFS解法详解

洛谷P2346四子连珠游戏最短步数BFS解法详解

一、题目解读洛谷P2346是一道经典的棋盘游戏问题,要求在一4x4黑白棋棋盘上,通过移动棋子使同色棋子形成四子一线(横、竖或对角线),计算达成目标所需的最少步数。题目考察BFS算法应用和状态空间搜索能...

牛客14496题解:括号最大深度问题(栈思想与代码优化)

牛客14496题解:括号最大深度问题(栈思想与代码优化)

一、题目解读牛客14496题要求计算给定括号字符串中的最大深度。例如,对于字符串 "(()())",最大深度为2。题目考察对括号嵌套结构的理解,以及如何通过编程找到最深嵌套层次。二...

洛谷1363题解法:虚拟坐标优化BFS解决循环迷宫问题(附代码详解)

洛谷1363题解法:虚拟坐标优化BFS解决循环迷宫问题(附代码详解)

一、题目解读洛谷1363题要求判断在给定大小的循环迷宫中,从起点出发是否可以通过移动到达多个不同的路径方向。迷宫由字符矩阵表示,'S'为起点,'#'为障碍物,其余为可通...

手搓顺序表实现栈 代码详解及新手教程——从原理到实现的完整指南

一、简介和特点顺序栈是一种基于数组实现的后进先出(LIFO)数据结构。通过动态数组管理存储空间,它具备以下特点:1. 数组存储:数据连续存储,支持随机访问,访问效率高。2. 动态扩容:当栈满时自动扩展...

牛客13278题详解:句子单词反转(C++实现)

牛客13278题详解:句子单词反转(C++实现)

一、题目解读牛客13278题要求编写函数实现句子中单词顺序的反转,例如将"Hello World"转换为"World Hello"。需注意处理首尾空格、单词间空...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。