@@ -105,14 +105,84 @@ class Solution:
105105 for dr, dc in neighors:
106106 nr, nc = r + dr, c + dc
107107 if 0 <= nr < M and 0 <= nc < N:
108- if A[nr][nc] == 0 : # meet and edge
108+ if A[nr][nc] == 0 :
109109 A[nr][nc] = - 2
110110 bfs.append((nr, nc))
111111 elif A[nr][nc] == 1 :
112112 return flip
113113 flip += 1
114114```
115115
116+ ## Dijkstra's Algorithm
117+
118+ 用于求解单源最短路径问题。思想是 greedy 构造 shortest path tree (SPT),每次将当前距离源点最短的不在 SPT 中的结点加入SPT,与构造最小生成树 (MST) 的 Prim's algorithm 非常相似。可以用 priority queue (heap) 实现。
119+
120+ ### [ network-delay-time] ( https://leetcode-cn.com/problems/network-delay-time/ )
121+
122+ 标准的单源最短路径问题,使用朴素的的 Dijikstra 算法即可,可以当成模板使用。
123+
124+ ``` Python
125+ class Solution :
126+ def networkDelayTime (self , times : List[List[int ]], N : int , K : int ) -> int :
127+
128+ # construct graph
129+ graph_neighbor = collections.defaultdict(list )
130+ for s, e, t in times:
131+ graph_neighbor[s].append((e, t))
132+
133+ # Dijkstra
134+ SPT = {}
135+ min_heap = [(0 , K)]
136+
137+ while min_heap:
138+ delay, node = heapq.heappop(min_heap)
139+ if node not in SPT :
140+ SPT [node] = delay
141+ for n, d in graph_neighbor[node]:
142+ if n not in SPT :
143+ heapq.heappush(min_heap, (d + delay, n))
144+
145+ return max (SPT .values()) if len (SPT ) == N else - 1
146+ ```
147+
148+ ### [ cheapest-flights-within-k-stops] ( https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/ )
149+
150+ 在标准的单源最短路径问题上限制了路径的边数,因此需要同时维护当前 SPT 内每个结点最短路径的边数,当遇到边数更小的路径 (边权和可以更大) 时结点需要重新入堆,以更新后继在边数上限内没达到的结点。
151+
152+ ``` Python
153+ class Solution :
154+ def findCheapestPrice (self , n : int , flights : List[List[int ]], src : int , dst : int , K : int ) -> int :
155+
156+ # construct graph
157+ graph_neighbor = collections.defaultdict(list )
158+ for s, e, p in flights:
159+ graph_neighbor[s].append((e, p))
160+
161+ # modified Dijkstra
162+ prices, steps = {}, {}
163+ min_heap = [(0 , 0 , src)]
164+
165+ while len (min_heap) > 0 :
166+ price, step, node = heapq.heappop(min_heap)
167+
168+ if node == dst: # early return
169+ return price
170+
171+ if node not in prices:
172+ prices[node] = price
173+
174+ steps[node] = step
175+ if step <= K:
176+ step += 1
177+ for n, p in graph_neighbor[node]:
178+ if n not in prices or step < steps[n]:
179+ heapq.heappush(min_heap, (p + price, step, n))
180+
181+ return - 1
182+ ```
183+
184+ ## 补充
185+
116186## Bidrectional BFS
117187
118188当求点对点的最短路径时,BFS遍历结点数目随路径长度呈指数增长,为缩小遍历结点数目可以考虑从起点 BFS 的同时从终点也做 BFS,当路径相遇时得到最短路径。
@@ -182,81 +252,13 @@ class Solution:
182252 return 0
183253```
184254
185- ## Dijkstra's Algorithm
186-
187- 用于求解单源最短路径问题。思想是 greedy 构造 shortest path tree (SPT),每次将当前距离源点最短的不在 SPT 中的结点加入SPT,与构造最小生成树 (MST) 的 Prim's algorithm 非常相似。可以用 priority queue (heap) 实现。
188-
189- ### [ network-delay-time] ( https://leetcode-cn.com/problems/network-delay-time/ )
190-
191- 标准的单源最短路径问题,使用朴素的的 Dijikstra 算法即可,可以当成模板使用。
192-
193- ``` Python
194- class Solution :
195- def networkDelayTime (self , times : List[List[int ]], N : int , K : int ) -> int :
196-
197- # construct graph
198- graph_neighbor = collections.defaultdict(list )
199- for s, e, t in times:
200- graph_neighbor[s].append((e, t))
201-
202- # Dijkstra
203- SPT = {}
204- min_heap = [(0 , K)]
205-
206- while min_heap:
207- delay, node = heapq.heappop(min_heap)
208- if node not in SPT :
209- SPT [node] = delay
210- for n, d in graph_neighbor[node]:
211- if n not in SPT :
212- heapq.heappush(min_heap, (d + delay, n))
213-
214- return max (SPT .values()) if len (SPT ) == N else - 1
215- ```
216-
217- ### [ cheapest-flights-within-k-stops] ( https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/ )
218-
219- 在标准的单源最短路径问题上限制了路径的边数,因此需要同时维护当前 SPT 内每个结点最短路径的边数,当遇到边数更小的路径 (边权和可以更大) 时结点需要重新入堆,以更新后继在边数上限内没达到的结点。
220-
221- ``` Python
222- class Solution :
223- def findCheapestPrice (self , n : int , flights : List[List[int ]], src : int , dst : int , K : int ) -> int :
224-
225- # construct graph
226- graph_neighbor = collections.defaultdict(list )
227- for s, e, p in flights:
228- graph_neighbor[s].append((e, p))
229-
230- # modified Dijkstra
231- prices, steps = {}, {}
232- min_heap = [(0 , 0 , src)]
233-
234- while len (min_heap) > 0 :
235- price, step, node = heapq.heappop(min_heap)
236-
237- if node == dst: # early return
238- return price
239-
240- if node not in prices:
241- prices[node] = price
242-
243- steps[node] = step
244- if step <= K:
245- step += 1
246- for n, p in graph_neighbor[node]:
247- if n not in prices or step < steps[n]:
248- heapq.heappush(min_heap, (p + price, step, n))
249-
250- return - 1
251- ```
252-
253- ## 补充:A* Algorithm
255+ ## A* Algorithm
254256
255257当需要求解有目标的最短路径问题时,BFS 或 Dijkstra's algorithm 可能会搜索过多冗余的其他目标从而降低搜索效率,此时可以考虑使用 A* algorithm。原理不展开,有兴趣可以自行搜索。实现上和 Dijkstra’s algorithm 非常相似,只是优先级需要加上一个到目标点距离的估值,这个估值严格小于等于真正的最短距离时保证得到最优解。当 A* algorithm 中的距离估值为 0 时 退化为 BFS 或 Dijkstra’s algorithm。
256258
257259### [ sliding-puzzle] ( https://leetcode-cn.com/problems/sliding-puzzle )
258260
259- 思路 1:BFS。为了方便对比 A* 算法写成了与其相似的形式。
261+ - 方法 1:BFS。为了方便对比 A* 算法写成了与其相似的形式。
260262
261263``` Python
262264class Solution :
@@ -300,7 +302,7 @@ class Solution:
300302 return - 1
301303```
302304
303- 思路 2:A* algorithm
305+ - 方法 2:A* algorithm
304306
305307``` Python
306308class Solution :
0 commit comments