【LeetCode】1129. 颜色交替的最短路径

1129. 颜色交替的最短路径

在一个有向图中,节点分别标记为 0, 1, ..., n-1。图中每条边为红色或者蓝色,且存在自环或平行边。

red_edges 中的每一个 [i, j] 对表示从节点 i 到节点 j 的红色有向边。类似地,blue_edges 中的每一个 [i, j] 对表示从节点 i 到节点 j 的蓝色有向边。

返回长度为 n 的数组 answer,其中 answer[X] 是从节点 0 到节点 X 的红色边和蓝色边交替出现的最短路径的长度。如果不存在这样的路径,那么 answer[x] = -1

示例 1:

输入:n = 3, red_edges = [[0,1],[1,2]], blue_edges = []
输出:[0,1,-1]

示例 2:

输入:n = 3, red_edges = [[0,1]], blue_edges = [[2,1]]
输出:[0,1,-1]

示例 3:

输入:n = 3, red_edges = [[1,0]], blue_edges = [[2,1]]
输出:[0,-1,-1]

示例 4:

输入:n = 3, red_edges = [[0,1]], blue_edges = [[1,2]]
输出:[0,1,2]

示例 5:

输入:n = 3, red_edges = [[0,1],[0,2]], blue_edges = [[1,0]]
输出:[0,1,1]

提示:

  • 1 <= n <= 100
  • red_edges.length <= 400
  • blue_edges.length <= 400
  • red_edges[i].length == blue_edges[i].length == 2
  • 0 <= red_edges[i][j], blue_edges[i][j] < n

思路

使用邻接表存储图,使用0和1来区分红色和蓝色,队列元素记录了结点和路径颜色。由于需要分类讨论两种初始情况,开始直接将两种颜色存入队列。中间使用cnt记录遍历深度以记录最短路径。最后求得的红蓝路径取最小值即可。

代码

class Solution {
    
    
public:
    vector<int> shortestAlternatingPaths(int n, vector<vector<int>>& redEdges, vector<vector<int>>& blueEdges) {
    
    
        // 记录距离 大小2 * n
        vector<vector<int>> dist(n, vector<int>(2, INT_MAX));
        // 邻接表,vector
        vector<pair<int, int>> roadmap[n];
        // 记录最短路径
        vector<int> ans(n);
        // 记录遍历深度
        int cnt = 0;
        for (auto edge : redEdges) // 红色记录0
            roadmap[edge[0]].emplace_back(edge[1], 0);
        for (auto edge : blueEdges) // 蓝色记录1
            roadmap[edge[0]].emplace_back(edge[1], 1);
        // 记录节点和路径颜色
        queue<pair<int, int>> que;
        que.emplace(0, 0); que.emplace(0, 1);
        dist[0][0] = dist[0][1] = 0;
        // 双端BFS
        while (!que.empty()) {
    
    
            int size = que.size();
            // 更新遍历深度
            ++cnt;
            // 遍历一层的所有元素
            for (int i = 0; i < size; ++i) {
    
    
                auto [x, y] = que.front(); que.pop();
                // 遍历邻接表
                for (int j = 0; j < roadmap[x].size(); ++j) {
    
    
                    // 获取邻接表的每个元素
                    int nx = roadmap[x][j].first;
                    int ny = roadmap[x][j].second;
                    // 位运算判断颜色是否交替,同时判断是否未遍历过
                    if (y ^ ny == 1 && dist[nx][ny] == INT_MAX) {
    
    
                        // 记录遍历深度,即路径长度
                        dist[nx][ny] = cnt;
                        // 下一个元素入队列
                        que.emplace(nx, ny);
                    }
                }
            }
        }
        for (int i = 0; i < n; ++i) {
    
    
            // ans取红蓝路径最小值
            ans[i] = min(dist[i][0], dist[i][1]);
            // 如果路径未遍历过,说明找不到路径
            if (ans[i] == INT_MAX) ans[i] = -1;
        }
        return ans;
    }
};

猜你喜欢

转载自blog.csdn.net/Keikei419/article/details/128877867