[M最短路] lc1129. 颜色交替的最短路径(bfs最短路+拆点+拆边+好题)
Posted Ypuyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[M最短路] lc1129. 颜色交替的最短路径(bfs最短路+拆点+拆边+好题)相关的知识,希望对你有一定的参考价值。
文章目录
1. 题目来源
2. 题目解析
来自2023年02月02日的每日一题,很不错的题目,大约 1780 分左右的题目。
从零点出发,求最短路,即单源最短路算法。但本题并非是经典的单源最短路模板题,因为走的是 “交替路径”。
在经典问题中只考虑边权、费用,在本题中,边权、费用为 1,但又要考虑 “交替路径”,待表示的状态多了一个维度。常用 拆点 的方法,定义一个状态表示。
单源最短路 dist
数组经典定义:
d[i]
表示 点i
到起点的最短路径长长度
本题拆点 dist
数组定义为:
d[i][j]
表示 点i
到起点,且来源边为状态j
。在此j
取值为 0, 1 即可,表示 红、蓝 边即可。
这样原图中的一个点,就被拆成了两个点,由于拆点前后图的定义已经发生了变化,要证明原图的所有方案与拆点后的新图的所有方案是一一等价的。即证明原图的任意一条路径可以转化与新图的路径做转化。简单可证。
此时,原图的交替路径最小值 等价于 新图的一般路径的最短路,新图已经转化为一般的最短路模型,bfs
求解即可。
简单总结:将原图变成一个更大的图,每个点变成一个二元组,第一项表示点的编号,第二项表示它的来源,如果是从红色的边到达的记为0,否则记为1
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
#define x first
#define y second
class Solution
public:
vector<int> shortestAlternatingPaths(int n, vector<vector<int>>& redEdges, vector<vector<int>>& blueEdges)
const int INF = 1e8;
// 邻接表定义
vector<vector<pair<int, int>>> g(n);
for (auto &r : redEdges) g[r[0]].push_back(r[1], 0);
for (auto &b : blueEdges) g[b[0]].push_back(b[1], 1);
// 距离数组定义
vector<vector<int>> dist(n, vector<int>(2, INF));
dist[0][0] = dist[0][1] = 0;
// 初始第一条边的接入边是蓝/红 均可
queue<pair<int, int>> q;
q.push(0, 0), q.push(0, 1);
while (q.size())
auto t = q.front(); q.pop();
// 枚举队列的所有出边
for (auto &p : g[t.x])
if (p.y != t.y && dist[p.x][p.y] > dist[t.x][t.y] + 1)
dist[p.x][p.y] = dist[t.x][t.y] + 1;
q.push(p);
vector<int> res;
for (int i = 0; i < n; i ++ )
res.push_back(min(dist[i][0], dist[i][1]));
if (res[i] == INF) res[i] = -1;
return res;
;
以上是关于[M最短路] lc1129. 颜色交替的最短路径(bfs最短路+拆点+拆边+好题)的主要内容,如果未能解决你的问题,请参考以下文章