题目
给定一个整数 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;
}
}