AcWing 920. 最优乘车 BFS DIJKSTRA SPFA 方法
地址 https://www.acwing.com/problem/content/description/922/
H城是一个旅游胜地,每年都有成千上万的人前来观光。 为方便游客, 巴士公司在各个旅游景点及宾馆,饭店等地都设置了巴士站并开通了一些单程巴士线路。 每条单程巴士线路从某个巴士站出发,依次途经若干个巴士站,最终到达终点巴士站。 一名旅客最近到H城旅游,他很想去S公园游玩, 但如果从他所在的饭店没有一路巴士可以直接到达S公园, 则他可能要先乘某一路巴士坐几站,再下来换乘同一站台的另一路巴士, 这样换乘几次后到达S公园。 现在用整数1,2,…N 给H城的所有的巴士站编号, 约定这名旅客所在饭店的巴士站编号为1,S公园巴士站的编号为N。 写一个程序,帮助这名旅客寻找一个最优乘车方案, 使他在从饭店乘车到S公园的过程中换乘的次数最少。 输入格式 第一行有两个数字M和N,表示开通了M条单程巴士线路,总共有N个车站。 从第二行到第M+1行依次给出了第1条到第M条巴士线路的信息, 其中第i+1行给出的是第i条巴士线路的信息, 从左至右按运行顺序依次给出了该线路上的所有站号, 相邻两个站号之间用一个空格隔开。 输出格式 共一行,如果无法乘巴士从饭店到达S公园,则输出”NO”, 否则输出最少换乘次数,换乘次数为0表示不需换车即可到达。 数据范围 1≤M≤100, 1≤N≤500 输入样例: 3 7 6 7 4 7 3 6 2 1 3 5 输出样例: 2
算法1
BFS
建图 每个车站到达后面的车站的距离都是1
那么1到达n的最短距离就是转车次数+1
比如例题中
1到2 3 5 都是距离1
2到 1 3 5 都是距离1
1先到3 3再到7 就是1到7的最短距离
C++ 代码

#include <iostream> #include <sstream> #include <queue> using namespace std; const int N = 510; int n, m; int stop[N]; /* 3 7 6 7 4 7 3 6 2 1 3 5 输出样例: 2 */ int g[N][N]; int bfs() { queue<pair<int,int>> q; for (int i = 1; i <= n; i++) { if (g[1][i] != 0) { q.push({ i,0 }); g[1][i] = 0; } } while (q.size()) { int currentStop = q.front().first; int step = q.front().second; q.pop(); if (currentStop == n) return step; for (int i = 1; i <= n; i++) { if (g[currentStop][i] != 0) { q.push({ i ,step+1}); g[currentStop][i] = 0; } } } return -1; } int main() { cin >> m >> n; string line; getline(cin, line); while (m--) { getline(cin, line); stringstream ssin(line); int cnt = 0, p; while (ssin >> p) stop[cnt++] = p; //每个汽车的前站达到后站的距离都为1 因为是同一辆车 未换车 for (int i = 0; i < cnt; i++) { for (int j = i + 1; j < cnt; j++) { g[stop[i]][stop[j]] = 1; } } } int ret = bfs(); if(-1==ret) cout << "NO" <<endl; else cout << ret <<endl; return 0; } 作者:itdef 链接:https://www.acwing.com/solution/content/15468/ 来源:AcWing 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
算法2
dijkstra

#include <iostream> #include <sstream> #include <memory.h> #include <queue> using namespace std; const int N = 510; int n, m; int stop[N]; /* 3 7 6 7 4 7 3 6 2 1 3 5 输出样例: 2 */ int g[N][N]; int dist[N]; bool st[N]; int dij() { memset(dist, 0x3f, sizeof dist); dist[1] = 0; for (int i = 0; i < n - 1; i++) { int t = -1; for (int j = 1; j <= n; j++) { if (!st[j] && (t == -1 || dist[t] > dist[j])) { t = j; } } for (int j = 1; j <= n; j++) { dist[j] = min(dist[j], dist[t] + g[t][j]); } st[t] = true; } return dist[n]; } int main() { cin >> m >> n; memset(g, 0x3f, sizeof g); string line; getline(cin, line); while (m--) { getline(cin, line); stringstream ssin(line); int cnt = 0, p; while (ssin >> p) stop[cnt++] = p; //每个汽车的前站达到后站的距离都为1 因为是同一辆车 未换车 for (int i = 0; i < cnt; i++) { for (int j = i + 1; j < cnt; j++) { g[stop[i]][stop[j]] = 1; } } } int ret = dij(); if ( ret > 0x3f3f3f3f/2) cout << "NO" << endl; else cout << ret-1 << endl; return 0; } 作者:itdef 链接:https://www.acwing.com/solution/content/15468/ 来源:AcWing 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
算法3
spfa
C++ 代码

#include <iostream> #include <sstream> #include <queue> #include <vector> #include <memory.h> using namespace std; const int N = 510; int n, m; int stop[N]; /* 3 7 6 7 4 7 3 6 2 1 3 5 输出样例: 2 */ vector<pair<int, int>> g[N]; int dist[N]; bool st[N]; int spfa() { memset(dist, 0x3f, sizeof dist); dist[1] = 0; queue<int> q; q.push(1); st[1] = true; while (q.size()) { int t = q.front(); q.pop(); st[t] = false; for (int i = 0; i < g[t].size(); i++) { int j = g[t][i].first; int w = g[t][i].second; if (dist[j] > dist[t] + w) { dist[j] = dist[t] + w; if (!st[j]) { q.push(j); st[j] = true; } } } } return dist[n]; } int main() { cin >> m >> n; string line; getline(cin, line); while (m--) { getline(cin, line); stringstream ssin(line); int cnt = 0, p; while (ssin >> p) stop[cnt++] = p; //每个汽车的前站达到后站的距离都为1 因为是同一辆车 未换车 for (int i = 0; i < cnt; i++) { for (int j = i + 1; j < cnt; j++) { g[stop[i]].push_back({ stop[j],1 }); } } } int ret = spfa(); if (ret == 0x3f3f3f3f) cout << "NO" << endl; else cout << ret -1 << endl; return 0; } 作者:itdef 链接:https://www.acwing.com/solution/content/15468/ 来源:AcWing 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力


【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话