1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- type minHeap [][3]int
- func (h minHeap) Len() int { return len(h) }
- func (h minHeap) Less(i, j int) bool { return h[i][0] < h[j][0] }
- func (h minHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
- func (h *minHeap) Push(x interface{}) {
- *h = append(*h, x.([3]int))
- }
- func (h *minHeap) Pop() interface{} {
- l := h.Len()
- x := (*h)[l-1]
- *h = (*h)[:l-1]
- return x
- }
- func cutOffTree(forest [][]int) (step int) {
- var h minHeap
- H, W := len(forest), len(forest[0])
- for y := range forest {
- for x, v := range forest[y] {
- if 1 < v {
- heap.Push(&h, [3]int{v, y, x})
- }
- }
- }
- beg := []int{0, 0}
- used := make([][]bool, H)
- for h.Len() != 0 {
- end := heap.Pop(&h).([3]int)
- for i := range used {
- used[i] = make([]bool, W)
- }
- ds := walk(forest, H, W, beg, end[1:], used)
- if ds == -1 {
- return -1
- }
- step += ds
- beg = end[1:]
- }
- return step
- }
- var dy = []int{0, 1, 0, -1}
- var dx = []int{1, 0, -1, 0}
- func walk(forest [][]int, H, W int, beg, end []int, used [][]bool) (step int) {
- queue := [][]int{beg}
- n := 1
- for len(queue) != 0 {
- pos := queue[0]
- queue = queue[1:]
- if pos[0] == end[0] && pos[1] == end[1] {
- return
- }
- for i := 0; i < 4; i++ {
- ny, nx := pos[0]+dy[i], pos[1]+dx[i]
- if 0 <= ny && ny < H && 0 <= nx && nx < W && !used[ny][nx] && forest[ny][nx] != 0 {
- queue = append(queue, []int{ny, nx})
- used[ny][nx] = true
- }
- }
- n--
- if n == 0 {
- step++
- n = len(queue)
- }
- }
- return -1
- }
|