Skip to content

Commit 9b88d4d

Browse files
committed
Path with Maximum Probability
1 parent ab2fb94 commit 9b88d4d

5 files changed

+140
-0
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
---
2+
title: Path with Maximum Probability
3+
---
4+
5+
### 描述
6+
7+
You are given an undirected weighted graph of `n` nodes (0-indexed), represented by an edge list where `edges[i] = [a, b]` is an undirected edge connecting the nodes a and b with a probability of success of traversing that edge `succProb[i]`.
8+
9+
Given two nodes `start` and `end`, find the path with the maximum probability of success to go from `start` to `end` and return its success probability.
10+
11+
If there is no path from `start` to `end`, **return 0**. Your answer will be accepted if it differs from the correct answer by at most **1e-5**.
12+
13+
**Example 1**:
14+
15+
![](/img/path-with-maximum-probability-example-1.png)
16+
17+
> **Input**: n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.2], start = 0, end = 2
18+
> **Output**: 0.25000
19+
> **Explanation**: There are two paths from start to end, one having a probability of success = 0.2 and the other has 0.5 \* 0.5 = 0.25.
20+
21+
**Example 2**:
22+
23+
![](/img/path-with-maximum-probability-example-2.png)
24+
25+
> **Input**: n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.3], start = 0, end = 2
26+
> **Output**: 0.30000
27+
28+
**Example 3**:
29+
30+
![](/img/path-with-maximum-probability-example-3.png)
31+
32+
> **Input**: n = 3, edges = [[0,1]], succProb = [0.5], start = 0, end = 2
33+
> **Output**: 0.00000
34+
> **Explanation**: There is no path between 0 and 2.
35+
36+
**Constraints**:
37+
38+
- $2 <= n <= 10^4$
39+
- 0 <= start, end < n
40+
- start != end
41+
- 0 <= a, b < n
42+
- a != b
43+
- 0 <= succProb.length == edges.length <= $2*10^4$
44+
- 0 <= succProb[i] <= 1
45+
- There is at most one edge between every two nodes.
46+
47+
### 分析
48+
49+
由于每条边的概率是介于[0,1]之间的正数,且路径上的概率是累乘起来的,那么对原图`G`中的每条边的权重取对数然后取反,就得到了一个边权在$[0, \infty)$之间的图`G'`,图`G`中“从起点到终点**成功概率最大**”的路径对应了图`G'`中“从起点到终点**边权之和最小**”的路径。由于图`G'`中没有负数边权,用 Dijkstra 算法最合适不过了。
50+
51+
### 代码
52+
53+
import Tabs from "@theme/Tabs";
54+
import TabItem from "@theme/TabItem";
55+
56+
<Tabs
57+
defaultValue="java"
58+
values={[
59+
{ label: 'Java', value: 'java', },
60+
{ label: 'C++', value: 'cpp', },
61+
]
62+
}>
63+
<TabItem value="java">
64+
65+
```java
66+
// Path with Maximum Probability
67+
// Dijkstra
68+
// Time Complexity: O(ElogN), Space Complexity: O(N + E)
69+
class Solution {
70+
public double maxProbability(int n, int[][] edges, double[] succProb, int start, int end) {
71+
// adjacency list, map<vertex_id, map<vertex_id, weight>>
72+
Map<Integer, Map<Integer, Double>> graph = new HashMap<>();
73+
for (int i = 0; i < edges.length; i++) {
74+
int[] edge = edges[i];
75+
double w = -Math.log(succProb[i]);
76+
// Undirected
77+
graph.putIfAbsent(edge[0], new HashMap<>());
78+
graph.get(edge[0]).put(edge[1], w);
79+
graph.putIfAbsent(edge[1], new HashMap<>());
80+
graph.get(edge[1]).put(edge[0], w);
81+
}
82+
83+
Map<Integer, Double> dist = dijkstra(graph, start);
84+
85+
return dist.containsKey(end) ? Math.exp(-dist.get(end)) : 0;
86+
}
87+
88+
/** Standard Dijkstra algorithm.
89+
*
90+
@param graph Adjacency list, map<vertex_id, map<vertex_id, weight>>.
91+
@param start The starting vertex ID.
92+
@return dist, map<vertex_id, distance>.
93+
*/
94+
private static Map<Integer, Double> dijkstra(Map<Integer, Map<Integer, Double>> graph, int start) {
95+
// map<vertex_id, distance>
96+
Map<Integer, Double> dist = new HashMap<>();
97+
// vertex_id -> father_vertex_id
98+
Map<Integer, Integer> father = new HashMap<>();
99+
100+
// pair<distance, vertex_id>, min heap, sorted by distance from start to vertex_id
101+
Queue<Pair<Double, Integer>> pq = new PriorityQueue<>((a, b) -> Double.compare(a.getKey(), b.getKey()));
102+
103+
// from start to start itself
104+
pq.offer(new Pair(0.0, start));
105+
dist.put(start, 0.0);
106+
107+
while(!pq.isEmpty()){
108+
final int u = pq.poll().getValue();
109+
if (!graph.containsKey(u)) continue; // leaf node
110+
111+
for(int v : graph.get(u).keySet()){
112+
final double w = graph.get(u).get(v);
113+
if (!dist.containsKey(v) || dist.get(u)+ w < dist.get(v)) {
114+
final double shorter = dist.get(u)+ w;
115+
dist.put(v, shorter);
116+
father.put(v, u);
117+
pq.offer(new Pair(shorter, v));
118+
}
119+
}
120+
}
121+
122+
return dist;
123+
}
124+
}
125+
```
126+
127+
</TabItem>
128+
<TabItem value="cpp">
129+
130+
```cpp
131+
// TODO
132+
```
133+
134+
</TabItem>
135+
</Tabs>
136+
137+
### 相关题目
138+
139+
- [Network Delay Time](network-delay-time.md)

sidebars.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ module.exports = {
345345
"graph/clone-graph",
346346
"graph/graph-valid-tree",
347347
"graph/network-delay-time",
348+
"graph/path-with-maximum-probability",
348349
],
349350
位操作: [
350351
"bitwise-operations/reverse-bits",
Loading
Loading
Loading

0 commit comments

Comments
 (0)