1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| package main
import ( "container/heap" "fmt" "math" )
func main() { graph := [][]int{ {1, 1, 0}, {1, 0, 1}, {0, 0, 0}, {0, 0, 1}, } n, m := len(graph), len(graph[0])
fmt.Println(dijkstra(graph)[n-1][m-1]) }
type State struct { x int y int distanceFromStart int }
func dijkstra(graph [][]int) [][]int { n, m := len(graph), len(graph[0]) minDistanceTo := make([][]int, n)
for i := range minDistanceTo { minDistanceTo[i] = make([]int, m) for j := range minDistanceTo[i] { minDistanceTo[i][j] = math.MaxInt } } minDistanceTo[0][0] = 0
pq := PriorityQueue{} heap.Push(&pq, &State{0, 0, 0})
directions := [][]int{ {1, 0}, {0, 1}, {0, -1}, }
for pq.Len() > 0 { currState := heap.Pop(&pq).(*State) currX, currY, currDist := currState.x, currState.y, currState.distanceFromStart
if minDistanceTo[currX][currY] < currDist { continue }
for _, d := range directions { nextX, nextY := currX+d[0], currY+d[1] if nextX >= n || nextY < 0 || nextY >= m { continue }
weight := 1 if graph[nextX][nextY] != graph[currX][currY] { weight += 1 }
distanceToNext := minDistanceTo[currX][currY] + weight
if distanceToNext < minDistanceTo[nextX][nextY] { minDistanceTo[nextX][nextY] = distanceToNext heap.Push(&pq, &State{nextX, nextY, distanceToNext}) } } }
return minDistanceTo }
type PriorityQueue []*State
func (pq PriorityQueue) Len() int { return len(pq) }
func (pq PriorityQueue) Less(i, j int) bool { return pq[i].distanceFromStart < pq[j].distanceFromStart }
func (pq PriorityQueue) Swap(i, j int) { pq[i], pq[j] = pq[j], pq[i] }
func (pq *PriorityQueue) Push(x interface{}) { *pq = append(*pq, x.(*State)) }
func (pq *PriorityQueue) Pop() interface{} { old := *pq n := len(old) item := old[n-1] old[n-1] = nil *pq = old[:n-1] return item }
|