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


原创内容 转载请注明出处

分享给朋友:

相关文章

洛谷4554题解:BFS算法优化最短路径求解(附代码详解)

洛谷4554题解:BFS算法优化最短路径求解(附代码详解)

一、题目解读洛谷4554题要求在一个n×m的网格中,计算从点(x1,y1)到点(x2,y2)的最短路径距离。路径上的每个格子包含字符,若相邻格子字符不同,则需要额外步数。题目核心在于处理字符差异对路径...

手搓邻接表类代码注释与详解:从零开始理解图数据结构(适合新手小白)

一、简介和特点邻接表是一种用于存储图(Graph)的数据结构,特别适合稀疏图(边数较少的图)。它通过链表的方式为每个节点维护其相邻节点的信息,既能高效节省空间,又能灵活支持图的动态操作。本文将基于您手...

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

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

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

牛客232639题解析:双指针+排序算法高效求解三角形数量(附代码详解)

牛客232639题解析:双指针+排序算法高效求解三角形数量(附代码详解)

一、题目解读牛客232639题要求计算一个整数数组中能够组成有效三角形的三边组合数量。根据三角形不等式,三边需满足任意两边之和大于第三边。例如,数组[3, 4, 5, 6]可组成两个有效三角形([3,...

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

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

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

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

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

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

发表评论

访客

看不清,换一张

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