1129. Shortest Path with Alternating Colors ⭐

Medium

You are given an integer n, the number of nodes in a directed graph where the nodes are labeled from 0 to n - 1. Each edge is red or blue in this graph, and there could be self-edges and parallel edges.

You are given two arrays redEdges and blueEdges where:

  • redEdges[i] = [ai, bi] indicates that there is a directed red edge from node ai to node bi in the graph, and

  • blueEdges[j] = [uj, vj] indicates that there is a directed blue edge from node uj to node vj in the graph.

Return an array answer of length n, where each answer[x] is the length of the shortest path from node 0 to node x such that the edge colors alternate along the path, or -1 if such a path does not exist.

Example 1:

Input: n = 3, redEdges = [[0,1],[1,2]], blueEdges = []
Output: [0,1,-1]

Example 2:

Input: n = 3, redEdges = [[0,1]], blueEdges = [[2,1]]
Output: [0,1,-1]

Constraints:

  • 1 <= n <= 100

  • 0 <= redEdges.length, blueEdges.length <= 400

  • redEdges[i].length == blueEdges[j].length == 2

  • 0 <= ai, bi, uj, vj < n

解題

func shortestAlternatingPaths(n int, red_edges [][]int, blue_edges [][]int) []int {
    // red[0] 會紀錄 node0 有通往哪些其他節點的紅邊
    // blue[0] 會紀錄 node0 有通往哪些其他節點的藍邊
    red := make([][]int, n) 
    blue := make([][]int, n) 
    
    for _, edge := range red_edges {
        red[edge[0]] = append(red[edge[0]], edge[1])
    }

    for _, edge := range blue_edges {
        blue[edge[0]] = append(blue[edge[0]], edge[1])
    }
    
    // BFS,queue 存放 這一層 level 要訪問的節點
    queue := make([][]int, 0)
    queue = append(queue, []int{0, -1}) // 從節點0出發,邊用 -1 特別記錄
    // res 記錄 0 到每個點的最短路徑,初始化為 -1,不可到達
    res := make([]int, n)
    for i := 0; i < n; i ++{
        res[i] = -1
    }
    
    // 記錄是否從紅藍邊通往某一點過
    // 例如:已經從紅邊訪問過節點3,那下次要從紅邊訪問節點3,路徑長必定大於之前紀錄的值,可以跳過
    visited := make([][]bool, n)
    for j := 0; j < n; j ++{
        visited[j] = []bool{false, false}
    }
    
    // level,也就是目前路境長
    level := 0
    
    // 沒有節點需要拜訪才跳出迴圈
    for len(queue) != 0 {
        next := [][]int{} // 下一層要遞迴的點
        for _, n := range queue { //遞迴拜訪這一層的點
            label := n[0] // 這個點的label
            color := n[1] // 這個點的顏色

            if color != -1 { 
                visited[label][color] = true // 其他點從紅邊或藍邊訪問過這個點了
            }
            // 第一次到這個點,目前是最短路徑!記錄起來
            if res[label] == -1 {
                res[label] = level
            }
            
            // 目前是藍色(color=0)或是在節點0,把紅色的邊與要去的點加到下一層要訪問的陣列中
            if color == 0 || color == -1 {
                for _, neighbor := range red[label] {
                    if !visited[neighbor][1] {
                        next = append(next, []int{neighbor, 1})
                    }
                }
            }
            
            // 目前是紅色(color=1)或是在節點0,把藍色的邊與要去的點加到下一層要訪問的陣列中
            if color == 1 || color == -1 {
                for _, neighbor := range blue[label] {
                    if !visited[neighbor][0] {
                        next = append(next, []int{neighbor, 0})
                    }
                }
            }
        }

        queue = next // 待會要訪問下一層了!
        level++ // 層數 == 路徑長 加1
    }

    return res
}



Last updated