675.cut-off-trees-for-golf-event.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. type minHeap [][3]int
  2. func (h minHeap) Len() int { return len(h) }
  3. func (h minHeap) Less(i, j int) bool { return h[i][0] < h[j][0] }
  4. func (h minHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
  5. func (h *minHeap) Push(x interface{}) {
  6. *h = append(*h, x.([3]int))
  7. }
  8. func (h *minHeap) Pop() interface{} {
  9. l := h.Len()
  10. x := (*h)[l-1]
  11. *h = (*h)[:l-1]
  12. return x
  13. }
  14. func cutOffTree(forest [][]int) (step int) {
  15. var h minHeap
  16. H, W := len(forest), len(forest[0])
  17. for y := range forest {
  18. for x, v := range forest[y] {
  19. if 1 < v {
  20. heap.Push(&h, [3]int{v, y, x})
  21. }
  22. }
  23. }
  24. beg := []int{0, 0}
  25. used := make([][]bool, H)
  26. for h.Len() != 0 {
  27. end := heap.Pop(&h).([3]int)
  28. for i := range used {
  29. used[i] = make([]bool, W)
  30. }
  31. ds := walk(forest, H, W, beg, end[1:], used)
  32. if ds == -1 {
  33. return -1
  34. }
  35. step += ds
  36. beg = end[1:]
  37. }
  38. return step
  39. }
  40. var dy = []int{0, 1, 0, -1}
  41. var dx = []int{1, 0, -1, 0}
  42. func walk(forest [][]int, H, W int, beg, end []int, used [][]bool) (step int) {
  43. queue := [][]int{beg}
  44. n := 1
  45. for len(queue) != 0 {
  46. pos := queue[0]
  47. queue = queue[1:]
  48. if pos[0] == end[0] && pos[1] == end[1] {
  49. return
  50. }
  51. for i := 0; i < 4; i++ {
  52. ny, nx := pos[0]+dy[i], pos[1]+dx[i]
  53. if 0 <= ny && ny < H && 0 <= nx && nx < W && !used[ny][nx] && forest[ny][nx] != 0 {
  54. queue = append(queue, []int{ny, nx})
  55. used[ny][nx] = true
  56. }
  57. }
  58. n--
  59. if n == 0 {
  60. step++
  61. n = len(queue)
  62. }
  63. }
  64. return -1
  65. }