题目
回顾一下Bellman-Ford算法
Bellman-Ford算法可以用来计算有权图中的最短路径。其远离就是对图中的每一条边调用"relax"函数。"relax"函数做了这样一件事:假设图中存在a, b, c三个点,ab如果小于ac + cb,那么ab之间的距离更新为ac + cb。伪代码如下:
for (int pass = 0; pass < G.V(); pass++)
for (v = 0; v < G.V(); v++)
for (DirectedEdge e : G.adj(v)) relax(e);
题解
这道题目问“从起点到终点成功概率最大的路径”,并且我们可以发现每条路径都是有权重的:edges对应不同的概率。所以,从已知信息可以发现这道题目用Bellman-Ford算法是可解的。
我们可以用dp数组(长度为结点的数量)来储存概率,并且全部初始化为0。到第i个元素的最大概率为dp[i]。这道题目需要对Bellman-Ford算法做一个小小的修改的地方就是假设图中存在a, b, c三个点,ab如果小于ac * cb,那么ab之间的距离更新为ac * cb。那么问题来了,既然我们把dp初始化为0,那么所有的点再怎么乘都是0呀。因此,需要把起始点的dp对应值初始化为1。
需要注意的是,这道题目中的图是无向图,所以当我们要把ab之间的距离更新为ac * cb的时候,不仅得把dp[b]改成ac * cb,还得把dp[a]也改为cb * ca。
class Solution:
def maxProbability(self, n: int, edges: List[List[int]], succProb: List[float], start: int, end: int) -> float:
edgesNum = len(edges)
dp = [0] * n
dp[start] = 1
while True:
changed = False
for i in range(edgesNum):
if dp[edges[i][1]] < succProb[i] * dp[edges[i][0]]:
dp[edges[i][1]] = succProb[i] * dp[edges[i][0]]
changed = True
if dp[edges[i][0]] < dp[edges[i][1]] * succProb[i]:
dp[edges[i][0]] = dp[edges[i][1]] * succProb[i]
changed = True
if not changed: break
return dp[end]
参考资料
[1] leetcode-cn.com/problems/pa…
[2] 算法(第四版)。[美]Robert Sedgewick, Kevin Wayne著