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

131 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情

一、题目描述:

1129. 颜色交替的最短路径 - 力扣(LeetCode)

在一个有向图中,节点分别标记为 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

二、思路分析:

  1. 将边转化为有向图的形式
  2. 分别从红蓝边开始进行两次BFS,取其中的较短距离
  3. 对于某个节点,存在分别从红蓝两边进入的两种情况,即每个节点可沿红蓝边各访问一次,需要两个数组分别标记从红和蓝边进入节点的情况,且由于第一轮BFS就会存在至多两次进入同一个节点的情况,因此初始距离只能设为最大

三、AC 代码:

class Solution {
    void bfs(vector<int> &ans,bool red,vector<vector<int>>& redMap,vector<vector<int>>& blueMap){
        int len=1,thisLenNum=1;
        //是否已考虑从红或蓝边进入某节点的两种需要分开判断
        vector<bool> redvis(ans.size(),false),bluevis(ans.size(),false);
        queue<int> que;
        que.emplace(0);       
        while(!que.empty()){
            while(thisLenNum--){
                int i=que.front();
                que.pop();
                if(red){
                    for(auto &nextRed:redMap[i])
                        if(!redvis[nextRed]){
                            redvis[nextRed]=true;
                            que.emplace(nextRed);
                            ans[nextRed]=min(len,ans[nextRed]);
                        }
                }
                else{
                    for(auto &nextBlue:blueMap[i])
                        if(!bluevis[nextBlue]){
                            bluevis[nextBlue]=true;
                            que.emplace(nextBlue);
                            ans[nextBlue]=min(len,ans[nextBlue]);
                        }                
                }
            }
            red=!red;
            thisLenNum=que.size();
            ++len;            
        }
    }
public:
    vector<int> shortestAlternatingPaths(int n, vector<vector<int>>& redEdges, vector<vector<int>>& blueEdges) {
        //转化为有向图的形式
        vector<vector<int>> redMap(n),blueMap(n);
        for(int i=0;i<redEdges.size();++i)
            redMap[redEdges[i][0]].emplace_back(redEdges[i][1]);
        for(int i=0;i<blueEdges.size();++i)
            blueMap[blueEdges[i][0]].emplace_back(blueEdges[i][1]);

        vector<int> ans(n,INT_MAX);
        ans[0]=0;        
        //第一次BFS从红边开始  
        bfs(ans,true,redMap,blueMap);     
        //第二次BFS从蓝边开始
        bfs(ans,false,redMap,blueMap);
        //将仍为INT_MAX的位置置为-1
        for(auto &i:ans)
            if(i==INT_MAX) i=-1;
        return ans;        
    }
};