67 lines
1.4 KiB
Go
67 lines
1.4 KiB
Go
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
|