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

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

22小时前

牛客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搜索实现最短路径查找。通过标记已访问公交车,避免重复遍历线路,显著优化时间复杂度。算法实现简洁高效,适用于大规模公交网络路径规划问题。


原创内容 转载请注明出处

分享给朋友:

相关文章

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

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

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

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

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

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

牛客NC67题解:汉诺塔递归算法与解题步骤

牛客NC67题解:汉诺塔递归算法与解题步骤

一、题目解读牛客NC67题要求解决汉诺塔问题,这是一个经典的递归算法题目。题目给定整数n,代表汉诺塔中的盘子数量,需要输出将n个盘子从起始柱移动到目标柱的所有步骤。汉诺塔问题规则为:每次只能移动一个盘...

LeetCode 537题解:复数乘法的C++高效实现与代码解析

LeetCode 537题解:复数乘法的C++高效实现与代码解析

一、题目解读LeetCode 537题要求实现两个复数的乘法,输入为形如"a+bi"的字符串,需输出乘积的复数形式。题目核心在于解析字符串中的实部与虚部,并应用复数乘法公式计算结果...

牛客4432题解题全解析:矩阵快速幂优化楼梯攀登问题(附C++代码)

牛客4432题解题全解析:矩阵快速幂优化楼梯攀登问题(附C++代码)

一、题目解读牛客4432题要求计算在n阶楼梯中,每次可爬1阶或2阶,共有多少种不同的攀登方式。该问题属于经典的动态规划类题目,需通过数学递推或矩阵乘法优化算法以应对较大数据规模。题目核心在于寻找高效计...

牛客4577题解:滑动窗口解法

牛客4577题解:滑动窗口解法

一、题目解读牛客4577题要求处理多组测试数据,每组包含一个整数数组crimes和两个参数n(数组长度)、t(阈值)、c(窗口大小)。题目需要统计数组中所有长度恰好为c的子数组,其元素和不超过t的数量...

发表评论

访客

看不清,换一张

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