# 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; } } ```