leetocde1129. 颜色交替的最短路径(bfs)

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

代码

class Solution {
    public int[] shortestAlternatingPaths(int n, int[][] red_edges, int[][] blue_edges) {

        int[] res=new int[n];
        Arrays.fill(res,Integer.MAX_VALUE);
        Map<Integer,List<Integer>> blue=new HashMap<>();
        Map<Integer,List<Integer>> red=new HashMap<>();
        for(int[] r:red_edges)//红边的邻接表
        {
            if(!red.containsKey(r[0])) red.put(r[0],new ArrayList<>());
           red.get(r[0]).add(r[1]);
        }
        for(int[] r:blue_edges)//蓝边的邻接表
        {
            if(!blue.containsKey(r[0])) blue.put(r[0],new ArrayList<>());
            blue.get(r[0]).add(r[1]);
        }
        int rob=1;
        Queue<Integer> queue=new LinkedList<>();
        int level=0;
        boolean[] rf=new boolean[n];//记录节点是不是已经被红边进入过
        boolean[] bf=new boolean[n];//记录节点是不是已经被蓝边进入过
        queue.add(0);
        while (!queue.isEmpty())//以红边为开始的bfs
        {
            int size=queue.size();
            for(int i=0;i<size;i++)
            {
                int cur=queue.poll();
                res[cur]=Math.min(level,res[cur]);
                if(rob==1)//下一条边是红边
                {
                    if(!red.containsKey(cur)) continue;//没有下一条边了
                    for(int c:red.get(cur))//满足条件的下一节点入队
                    {
                        if(!rf[c])
                        {
                            queue.offer(c);
                            rf[c]=true;
                        }
                    }

                }else{//下一条边是蓝边
                    if(!blue.containsKey(cur)) continue;
                    for(int c:blue.get(cur))
                    {
                        if(!bf[c]) 
                        {
                          queue.offer(c);  
                           bf[c]=true;
                        }
                    }

                }
            }
            rob=rob==1?2:1;//替换下一条边颜色
            level++;
        }
             rob=2;
     
         level=0;
       rf=new boolean[n];
         bf=new boolean[n];
        queue.add(0);
        while (!queue.isEmpty())
        {
            int size=queue.size();
            for(int i=0;i<size;i++)
            {
                int cur=queue.poll();
                res[cur]=Math.min(level,res[cur]);
                if(rob==1)
                {
                    if(!red.containsKey(cur)) continue;
                    for(int c:red.get(cur))
                    {
                        if(!rf[c])
                        {
                            queue.offer(c);
                            rf[c]=true;
                        }
                    }

                }else{
                    if(!blue.containsKey(cur)) continue;
                    for(int c:blue.get(cur))
                    {
                        if(!bf[c]) 
                        {
                          queue.offer(c);  
                           bf[c]=true;
                        }
                    }

                }
            }
            rob=rob==1?2:1;
            level++;
        }
        for(int i=0;i<n;i++) if(res[i]==Integer.MAX_VALUE) res[i]=-1;//将不能到达的节点置为-1
        return res;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_44560620/article/details/107636135