---
# System prepended metadata

title: 1514. Path with Maximum Probability
tags: [Leetcode, BFS, Dijkstra, Priority Queue, Medium]

---

# 1514. Path with Maximum Probability
###### tags: `Leetcode` `Medium` `Dijkstra` `Priority Queue` `BFS`
Link: https://leetcode.com/problems/path-with-maximum-probability/
## 思路 O((V+E)logV) O(V+E)
[Dijkstra算法介绍](https://zhuanlan.zhihu.com/p/40338107)
适用于找起点到终点有最小/最大xx值的路径
每次拿priority queue里面的top，然后把这个top能到达的所有点对应的新value算一下，如果比之前的更好，就加进priority queue里面（这样可能会造成重复），但是不影响结果，但是要注意的是存prev的值并不能让整个code变快，因为priority queue里的全部值不会因为prob table里面值的更新而全部更新，一个idx，在insert进去的时候prob值是多少决定了它在priority queue的位置，that is，两个一样的index不一定在被pop出来的时候是紧挨着的
因为priority queue里面会有duplicate nodes，所以时间复杂度不是O(E+VlogV)

**要注意的是由于priority queue里面存的是integer，但是比较的是double，所以它自带的compare函数的参数应该是integer，而不是double，因此要写成```Queue<Integer> pq = new PriorityQueue<Integer>(Comparator.comparingDouble(i -> -prob[i]));```**

由于一个之前的错误写法困扰了我很久就也放在下面了
之前在priority queue里面装的是node idx 比较的是prob[i]
后来的写法改成priority queue里面装当时拿到的prob和idx
前者priority queue里面会根据已经update了的prob排序
但是后者只会根据当时存下来的prob排序
## Code
```java=
class Solution {
    public double maxProbability(int n, int[][] edges, double[] succProb, int start, int end) {
        List<List<int[]>> graph = new ArrayList<>();
        for(int i=0; i<n; i++){
            graph.add(new ArrayList<>());
        }
        for(int i=0; i<edges.length; i++){
            int[] edge = edges[i];
            graph.get(edge[0]).add(new int[]{edge[1], i});
            graph.get(edge[1]).add(new int[]{edge[0], i});
        }
        
        double[] prob = new double[n];
        Queue<double[]> pq = new PriorityQueue<>(Comparator.comparingDouble(a->-a[0]));
        pq.add(new double[]{1.0, start*1.0});
        prob[start] = 1;
        
        while(!pq.isEmpty()){
            double[] curr = pq.poll();
            int idx = (int)curr[1];
            if(idx==end) return curr[0];
            double currProb = curr[0];
            for(int[] next:graph.get(idx)){
                if(currProb*succProb[next[1]]>prob[next[0]]){
                    prob[next[0]]=currProb*succProb[next[1]];
                    pq.add(new double[]{prob[next[0]], next[0]*1.0});
                }
            }
        }
        return 0;
    }
}
```
之前的错误写法
```java=
class Solution {
    public double maxProbability(int n, int[][] edges, double[] succProb, int start, int end) {
        Map<Integer, List<int[]>> map = new HashMap<>();
        for(int i = 0;i < edges.length;i++){
            int u = edges[i][0];
            int v = edges[i][1];
            if(!map.containsKey(u)){
                map.put(u, new ArrayList<>());
            }
            if(!map.containsKey(v)){
                map.put(v, new ArrayList<>());
            }
            map.get(u).add(new int[]{v,i});
            map.get(v).add(new int[]{u,i});
        }
        
        double[] prob = new double[n];
        prob[start] = 1;
        Queue<Integer> pq = new PriorityQueue<Integer>(Comparator.comparingDouble(i -> -prob[i]));
        pq.add(start);
        while(!pq.isEmpty()){
            int curr = pq.poll();
            if(curr == end){
                return prob[end];
            }
            for(int[] next : map.getOrDefault(curr, new ArrayList<>())){
                int neighbor = next[0];
                int idx = next[1];
                if(prob[neighbor] < prob[curr]*succProb[idx]){
                    prob[neighbor] = prob[curr]*succProb[idx];
                    pq.add(neighbor);
                }
            }
        }
        return 0;
    }
}
```