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]

代码

class Solution 
{
    
    
    public:
        vector<int> shortestAlternatingPaths(int n, vector<vector<int>>& red_edges, vector<vector<int>>& blue_edges)
        {
    
    
            // 由于存在自环或者平行边,所以定义哈希表保存每个结点对应的多条边并初始化
            unordered_map<int, vector<int>> redGraph;
            unordered_map<int, vector<int>> blueGraph;
            for(auto& red: red_edges) redGraph[red[0]].push_back(red[1]);
            for(auto& blue: blue_edges) blueGraph[blue[0]].push_back(blue[1]);

            // 由于存在环和平行边,用数组 visit[x][y][color]=true 代表从节点x到节点y的且颜色为color的边被访问过,防止重复访问
            // 第三维[2]有两维,第0维代表红色是否访问,第1维代表蓝色是否访问
            // 所有的点初始化为0代表为被访问过
            int visit[100][100][2];
            memset(visit,0,sizeof(visit));

            // step用于记录当前的步长,即从节点0到各节点的步长,从0逐渐+1自增
            // res代表节点 0 到节点 X 的最短路径的长度,初始化为最大值
            int step = 0;
            vector<int> res(n, INT_MAX);

            // 定义队列进行BFS,并进行初始化,pair<int, int>的意思是 <当前节点, 路径上颜色>
            // 队列初始化先进<0, 1>, 再进<0, 0>,即我们先访问蓝色,再访问红色。
            queue<pair<int, int>> myQue;
            myQue.push(make_pair(0, 1));
            myQue.push(make_pair(0, 0));

            while(!myQue.empty())
            {
    
    
                int size = myQue.size();
                ++step;

                for(int i=0; i < size; i++)
                {
    
    
                    // 队首元素出队列,得到其节点,以及颜色
                    int curNode = myQue.front().first;
                    int curColor = myQue.front().second;
                    myQue.pop();

                    //若当前已访问的为蓝色边,希望下一个节点的边是红色;反之亦然
                    if(curColor == 1)
                    {
    
    
                        // 遍历当前节点每一个相邻的节点,寻找相连的红色边
                        for(auto& nextNode: blueGraph[curNode])
                        {
    
    
                            // 如果 curNode 和 nextNode 相连的红色边未被访问过,访问并加入队列
                            // 同时需要更新两点之间的最短路径
                            if(visit[curNode][nextNode][0] == 0)
                            {
    
    
                                res[nextNode] = min(res[nextNode], step);
                                
                                // make_pair<nextNode, 0> 的含义是标记当前访问的边为红色,下次应该访问蓝色的
                                myQue.push(make_pair(nextNode, 0));
                                visit[curNode][nextNode][0] = 1;
                            }
                        }
                    }
                    else if(curColor == 0)
                    {
    
    
                        // 遍历当前节点每一个相邻的节点,寻找相连的蓝色边
                        for(auto& nextNode: redGraph[curNode])
                        {
    
    
                            // 如果 curNode 和 nextNode 相连的蓝色边未被访问过,访问并加入队列
                            // 同时需要更新两点之间的最短路径
                            if(visit[curNode][nextNode][1] == 0)
                            {
    
    
                                res[nextNode] = min(res[nextNode], step);

                                // make_pair<nextNode, 1> 的含义是标记当前访问的边为蓝色,下次应该访问红色的
                                myQue.push(make_pair(nextNode, 1));
                                visit[curNode][nextNode][1] = 1;
                            }
                        }
                    }
                }
            }

            // 根据题意,0 到自身的距离为0;在上述操作后,若 0 到其他节点距离仍为INT_MAX,说明不存在符合要求的路径,设置为-1;
            res[0] = 0;
            for(int i=0; i < n; i++) if(res[i] == INT_MAX) res[i] = -1;

            return res;
        }
};

作者:godwriter
链接:https://leetcode-cn.com/problems/shortest-path-with-alternating-colors/solution/czhi-nan-shen-mei-de-bfsshi-xian-fu-chao-xiang-xi-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

猜你喜欢

转载自blog.csdn.net/qq_45602618/article/details/114261409