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 mainimport ( "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 []*Statefunc (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 }
Copy