1514. 概率最大的路径
大约 3 分钟
--- 

1514. 概率最大的路径
- 标签:图、数组、最短路、堆(优先队列)
- 难度:中等
题目链接
题目大意
描述:给定一个 个节点的无向图,边集 和概率 。 表示从 到 的成功概率。
要求:返回从 到 的最大成功概率。如果不可达,返回 。
说明:
- 。
- 。
- 。
示例:
- 示例 1:

输入:n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.2], start = 0, end = 2
输出:0.25000
解释:从起点到终点有两条路径,其中一条的成功概率为 0.2 ,而另一条为 0.5 * 0.5 = 0.25- 示例 2:

输入:n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.3], start = 0, end = 2
输出:0.30000解题思路
思路 1:Dijkstra 变体(最大乘积路径)
1. 核心思想
路径概率 = 各边概率的乘积。要最大化从起点到终点的概率乘积。
这是最长路径问题的变体,但由于概率 ,取对数后转化为最短路。不过更直接的方法是使用 Dijkstra 的变体:用最大堆替换最小堆,每次取概率最大的路径扩展。
由于概率在 之间,乘积不会越乘越大,因此可以用贪心(Dijkstra 的贪心性质依然成立:当前概率最大的路径一定是该节点的最优路径)。
2. 具体步骤
第 1 步:建无向图,邻接表存 。
第 2 步:初始化 ,其他为 。最大堆 。
第 3 步:当堆非空:
- 弹出 。
- 如果 ,跳过。
- 如果 ,直接返回 (贪心保证第一次弹出终点时就是最大概率)。
- 遍历邻居 :
- 如果 :更新 ,入堆。
第 4 步:返回 。
3. 举例说明
以 为例:
0 --0.5-- 1
| /
0.2 0.5
| /
| /
2- ,堆:。
- 弹出 :邻居 ,;邻居 ,。
- 弹出 :邻居 ,,。
- 如果先弹出 :不是终点时继续。
最大概率路径:,概率 。
思路 1:代码
import heapq
class Solution:
def maxProbability(self, n: int, edges: List[List[int]], succProb: List[float], start: int, end: int) -> float:
graph = [[] for _ in range(n)]
for (u, v), p in zip(edges, succProb):
graph[u].append((v, p))
graph[v].append((u, p))
dist = [0.0] * n
dist[start] = 1.0
pq = [(-1.0, start)] # 最大堆,取负数
while pq:
prob, u = heapq.heappop(pq)
prob = -prob
if u == end:
return prob
if prob < dist[u]:
continue
for v, p in graph[u]:
new_prob = prob * p
if new_prob > dist[v]:
dist[v] = new_prob
heapq.heappush(pq, (-new_prob, v))
return 0.0思路 1:复杂度分析
- 时间复杂度:。
- 空间复杂度:。