CSES 1667 Message Route 题解
Message Route
题目大意
有
- 如连通,输出最短路径长度和任意一条最短路径中包含的所有点
- 如不连通,输出
IMPOSSIBLE
思路
首先,我们要大致了解一下最短路,利用BFS
,我们可以用 O(n + m) 的时间复杂度来求出从
可以用vector
去存储每条边,即邻接表。
BFS
首先,将初始状态加入到队列当中。
- 处理队头,可以转移到许多的点上。
· 先要弹出队头
· 如果当前转移到的点没有被遍历过,那么这个点的最短路径肯定是由队头转移而来。由于要记录路径,那么在这里记录一下这个点是由队头转移而来。
· 如果遍历过了,那么长度肯定不会比当前路径还要短,所以不需要记录。 - 如果队列空了,那么其他没有入过队列的节点肯定与节点
是不连通的。结束bfs
- 如果队列非空,那么执行操作
最后判断答案,输出答案即可。
路径输出详见代码注释。
Code
点击查看代码
#include <iostream> #include <queue> #include <vector> using namespace std; const int N = 1e5 + 10; int n, m, x, y, vis[N], fa[N], q[N], h, t; vector<int> v[N]; void record (int x_, int x, int lv) { // 处理当前队头转移到的点 if (vis[x]) { // 它已经被遍历过 return ; } vis[x] = lv; q[t++] = x; fa[x] = x_; // 记录 bfs 树中当前节点的父亲 } void bfs () { record(1, 1, 1); // 处理初始状态 while (h < t) { int _ = q[h++]; for (int i = 0; i < v[_].size(); i++) { // 队头能够转移到的点 record(_, v[_][i], vis[_] + 1); } } } void Print (int x) { // 输出路径处理 if (x != 1) { // 它不是开始的点 Print(fa[x]); // 先要去遍历它的父亲 } cout << x << ' '; // 输出当前的点 } int main(){ cin >> n >> m; for (int i = 1; i <= m; i++) { cin >> x >> y; v[x].push_back(y); v[y].push_back(x); // 无向图 } bfs(); if (!vis[n]) { // 非连通 cout << "IMPOSSIBLE"; } else { cout << vis[n] << '\n'; Print(n); } return 0; }
本文作者:wnsyou の blog
本文链接:https://www.cnblogs.com/wnsyou-blog/p/17117618.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步