1. 程式人生 > 其它 >1514. 概率最大的路徑(最大堆+dijkstral)

1514. 概率最大的路徑(最大堆+dijkstral)

1514. 概率最大的路徑

給你一個由 n 個節點(下標從 0 開始)組成的無向加權圖,該圖由一個描述邊的列表組成,其中 edges[i] = [a, b] 表示連線節點 a 和 b 的一條無向邊,且該邊遍歷成功的概率為 succProb[i] 。

指定兩個節點分別作為起點 start 和終點 end ,請你找出從起點到終點成功概率最大的路徑,並返回其成功概率。

如果不存在從 start 到 end 的路徑,請 返回 0 。只要答案與標準答案的誤差不超過 1e-5 ,就會被視作正確答案。

示例 1:

輸入:n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.2], start = 0, end = 2
輸出:0.25000
解釋:從起點到終點有兩條路徑,其中一條的成功概率為 0.2 ,而另一條為 0.5 * 0.5 = 0.25

示例 2:

輸入:n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.3], start = 0, end = 2
輸出:0.30000

示例 3:

輸入:n = 3, edges = [[0,1]], succProb = [0.5], start = 0, end = 2
輸出:0.00000
解釋:節點 0 和 節點 2 之間不存在路徑

提示:

  • 2 <= n <= 10^4
  • 0 <= start, end < n
  • start != end
  • 0 <= a, b < n
  • a != b
  • 0 <= succProb.length == edges.length <= 2*10^4
  • 0 <= succProb[i] <= 1
  • 每兩個節點之間最多有一條邊
 1 class Solution {
 2 public:
 3     double maxProbability(int n, vector<vector<int>>& edges, vector<double>& succProb, int start, int end) {
 4         // 1、採用鄰接表構建無向圖
 5         vector<vector<std::pair<int, double>>> graph(n); //
pair對(終點,起點到終點成功概率值) 6 for (unsigned int i = 0; i < edges.size(); i++) { 7 auto &edge = edges[i]; 8 graph[edge[0]].emplace_back(edge[1], succProb[i]); 9 graph[edge[1]].emplace_back(edge[0], succProb[i]); 10 } 11 // 2、採用優先佇列儲存pair對(起點到終點成功概率值,終點) 12 vector<double> prob(n, 0.0); // 儲存起點到各點的成功概率值,初始化概率為最小值 13 prob[start] = 1.0; // 初始化起點到起點的成功率為1 14 priority_queue<std::pair<int, double>> q; // 預設採用最大堆 15 q.emplace(start, 1.0); // 起點入隊 16 while (!q.empty()) { 17 auto [curNode, curProb] = q.top(); // 當前節點資訊[頂點, 邊]->[當前節點, 起點到該節點的成功概率] 18 q.pop(); 19 if (curProb < prob[curNode]) { /* 如果儲存的概率已經大於當前概率, 跳過節點 */ 20 continue; 21 } 22 /* 從curNode更新相鄰節點nextNode的最大概率 */ 23 for (auto [nextNode, nextProb] : graph[curNode] ) { 24 if (prob[nextNode] < prob[curNode] * nextProb) { 25 prob[nextNode] = prob[curNode] * nextProb; 26 q.emplace(nextNode, prob[nextNode]); 27 } 28 } 29 } 30 return prob[end]; 31 } 32 };