package q1466 import "math" func walk(connections [][2][]int, minFlips []int32, node int) { mf := minFlips[node] // Walk no-flip-needed for _, n := range connections[node][1] { if mf < minFlips[n] { minFlips[n] = mf walk(connections, minFlips, n) } } // Walk flip-needed for _, n := range connections[node][0] { if mf+1 < minFlips[n] { minFlips[n] = mf + 1 walk(connections, minFlips, n) } } } func collect(connections [][2][]int, minFlips []int32, node int, visited []bool) int32 { mf := minFlips[node] var sum int32 for _, n := range connections[node][1] { if !visited[n] && mf == minFlips[n] { visited[n] = true sum += collect(connections, minFlips, n, visited) - mf } } for _, n := range connections[node][0] { if !visited[n] && mf+1 == minFlips[n] { visited[n] = true sum += collect(connections, minFlips, n, visited) - mf } } return sum + mf } func minReorder(n int, connections [][]int) int { conns := make([][2][]int, n) for i := range connections { from, to := connections[i][0], connections[i][1] conns[from][0] = append(conns[from][0], to) conns[to][1] = append(conns[to][1], from) } minFlips := make([]int32, n) // minimum flips to reach node n minFlips[0] = math.MaxInt32 for i := 1; i < len(minFlips); i *= 2 { copy(minFlips[i:], minFlips[:i]) } minFlips[0] = 0 walk(conns, minFlips, 0) visited := make([]bool, n) return int(collect(conns, minFlips, 0, visited)) } var _ = minReorder