LC:1129 颜色交替的最短路径

223 阅读1分钟

题目

给定一个整数 n,即有向图中的节点数,其中节点标记为 0 到 n - 1。图中的每条边为红色或者蓝色,并且可能存在自环或平行边。

给定两个数组 redEdges 和 blueEdges,其中:

  • redEdges[i] = [ai, bi] 表示图中存在一条从节点 ai 到节点 bi 的红色有向边,
  • blueEdges[j] = [uj, vj] 表示图中存在一条从节点 uj 到节点 vj 的蓝色有向边。

返回长度为 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]

解法

class Solution {
    public int[] shortestAlternatingPaths(int n, int[][] redEdges, int[][] blueEdges) {
        List<Integer>[][] edges = new ArrayList[2][n];
        // 0 - red, 1 - blue
        for(int i = 0;i < 2;i ++) {
            for(int j = 0;j  < n;j ++) {
                edges[i][j] = new ArrayList<Integer>();
            }
        }
        for(int[] t : redEdges) {
            edges[0][t[0]].add(t[1]);
        }
        for(int[] t : blueEdges) {
            edges[1][t[0]].add(t[1]);
        }
        Queue<int[]> q = new ArrayDeque<>();
        int[][] dis = new int[n][2];
        for(int i = 0;i < n;i ++) {
            Arrays.fill(dis[i], Integer.MAX_VALUE);
        }
        dis[0][0] = 0;
        dis[0][1] = 0;
        q.offer(new int[]{0, 1});
        q.offer(new int[]{0, 0});
        while(!q.isEmpty()) {
            int[] now = q.poll();
            int x = now[0], c = now[1];
            for(int j : edges[1 - c][x]) {
                if(dis[j][1 - c] != Integer.MAX_VALUE) continue;
                dis[j][1 - c] = dis[x][c] + 1;
                // 一定要把数组压进去Queue里面
                q.offer(new int[]{j, 1 - c});
            }
        }
        int[] ans = new int[n];
        for(int i = 0;i < n;i ++) {
            ans[i] = Math.min(dis[i][0], dis[i][1]);
            if(ans[i] == Integer.MAX_VALUE) {
                ans[i] = -1;
            }
        }
        return ans;
    }
}