DSA Graphs

Path with Maximum Probability

Dijkstra with max-heap on the product of edge probabilities.

Medium
Time O((V + E) log V) Space O(V + E)
LeetCode
6 min read
graph dijkstra shortest-path

Problem#

An undirected graph; edge i between edges[i][0] and edges[i][1] has success probability succProb[i]. Find the maximum probability path from start to end; return 0 if no path exists.

Examples#

  • n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.2], start = 0, end = 20.25
  • n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.3], start = 0, end = 20.3

Constraints#

  • 2 <= n <= 10^4, 0 <= edges.length <= 2*10^4, 0 <= succProb[i] <= 1.

Approach#

Dijkstra in “maximize product” mode. Use a max-heap keyed by current path probability; relax edge (u, v, p) if prob[u] * p > prob[v].

Solution#

Path with Maximum Probability
class Solution {
public:
double maxProbability(int n, vector<vector<int>>& edges, vector<double>& succProb,
int start_node, int end_node) {
vector<vector<pair<int,double>>> adj(n);
for (int i = 0; i < (int)edges.size(); ++i) {
adj[edges[i][0]].push_back({edges[i][1], succProb[i]});
adj[edges[i][1]].push_back({edges[i][0], succProb[i]});
}
vector<double> prob(n, 0.0);
prob[start_node] = 1.0;
priority_queue<pair<double,int>> pq;
pq.push({1.0, start_node});
while (!pq.empty()) {
auto [p, u] = pq.top(); pq.pop();
if (u == end_node) return p;
if (p < prob[u]) continue;
for (auto [v, w] : adj[u]) {
double np = p * w;
if (np > prob[v]) {
prob[v] = np;
pq.push({np, v});
}
}
}
return 0.0;
}
};

Editorial#

Multiplying probabilities is a monotonic non-increasing operation on [0, 1], so the Dijkstra invariant holds: the first time we pop a node, we’ve found its maximum-probability path. Equivalently, taking -log(p) converts this to standard sum-Dijkstra on non-negative weights.

Complexity#

  • Time: O((V + E) log V).
  • Space: O(V + E).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.