列表

详情


1514. 概率最大的路径

给你一个由 n 个节点(下标从 0 开始)组成的无向加权图,该图由一个描述边的列表组成,其中 edges[i] = [a, b] 表示连接节点 a 和 b 的一条无向边,且该边遍历成功的概率为 succProb[i]

指定两个节点分别作为起点 start 和终点 end ,请你找出从起点到终点成功概率最大的路径,并返回其成功概率。

如果不存在从 startend 的路径,请 返回 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 之间不存在路径

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: double maxProbability(int n, vector<vector<int>>& edges, vector<double>& succProb, int start, int end) { } };

golang 解法, 执行用时: 104 ms, 内存消耗: 7.9 MB, 提交时间: 2023-09-26 20:14:56

func maxProbability(n int, edges [][]int, succProb []float64, start int, end int) float64 {
    graph := make([][]state, n)
    for i:=0; i<len(edges); i++ { //创建图
        edge := edges[i]
        graph[edge[0]] = append(graph[edge[0]], state{edge[1], succProb[i]})
        graph[edge[1]] = append(graph[edge[1]], state{edge[0], succProb[i]})
    }
    dist := make([]float64, n) //最大距离数组
    dist[start] = 1
    h := &hp{{start, 1}}
    for 0 < h.Len() {
        cur := heap.Pop(h).(state)
        if cur.id == end { //如果找到end节点,直接返回
            return cur.dist
        }
        if cur.dist < dist[cur.id] { //如果当前路径小于最大距离,则舍弃
            continue
        }
        
        for _, next := range graph[cur.id] {
            if d := cur.dist * next.dist; d > dist[next.id] { //如果从start到cur节点再到next节点的距离大于已知start到next最大距离,则更新
                dist[next.id] = d
                heap.Push(h, state{next.id, d})
            }
        }
    }
    
    return dist[end]
}

type state struct { 
    id int
    dist float64
}

// 大根堆
type hp []state
func (h hp) Len() int   {return len(h)}
func (h hp) Less(i, j int) bool {return h[i].dist > h[j].dist} //注意这个地方
func (h hp) Swap(i, j int)  {h[i], h[j] = h[j], h[i]}
func (h *hp) Push(v interface{}) {*h = append(*h, v.(state))}
func (h *hp) Pop() (v interface{}) {
    *h, v = (*h)[:h.Len()-1],(*h)[h.Len()-1]
    return
}

python3 解法, 执行用时: 192 ms, 内存消耗: 26.4 MB, 提交时间: 2023-09-26 20:14:31

class Solution:
    def maxProbability(self, n: int, edges: List[List[int]], succProb: List[float], start: int, end: int) -> float:
        graph = collections.defaultdict(list)
        for i, (x, y) in enumerate(edges):
            graph[x].append((succProb[i], y))
            graph[y].append((succProb[i], x))
        
        que = [(-1.0, start)]
        prob = [0.0] * n
        prob[start] = 1.0

        while que:
            pr, node = heapq.heappop(que)
            pr = -pr
            if pr < prob[node]:
                continue
            for prNext, nodeNext in graph[node]:
                if prob[nodeNext] < prob[node] * prNext:
                    prob[nodeNext] = prob[node] * prNext
                    heapq.heappush(que, (-prob[nodeNext], nodeNext))
        
        return prob[end]

java 解法, 执行用时: 34 ms, 内存消耗: 53.9 MB, 提交时间: 2023-09-26 20:14:08

class Solution {
    public double maxProbability(int n, int[][] edges, double[] succProb, int start, int end) {
        List<List<Pair>> graph = new ArrayList<List<Pair>>();
        for (int i = 0; i < n; i++) {
            graph.add(new ArrayList<Pair>());
        }
        for (int i = 0; i < edges.length; i++) {
            int[] e = edges[i];
            graph.get(e[0]).add(new Pair(succProb[i], e[1]));
            graph.get(e[1]).add(new Pair(succProb[i], e[0]));
        }

        PriorityQueue<Pair> que = new PriorityQueue<Pair>();
        double[] prob = new double[n];

        que.offer(new Pair(1, start));
        prob[start] = 1;
        while (!que.isEmpty()) {
            Pair pair = que.poll();
            double pr = pair.probability;
            int node = pair.node;
            if (pr < prob[node]) {
                continue;
            }
            for (Pair pairNext : graph.get(node)) {
                double prNext = pairNext.probability;
                int nodeNext = pairNext.node;
                if (prob[nodeNext] < prob[node] * prNext) {
                    prob[nodeNext] = prob[node] * prNext;
                    que.offer(new Pair(prob[nodeNext], nodeNext));
                }
            }
        }
        return prob[end];
    }
}

class Pair implements Comparable<Pair> {
    double probability;
    int node;

    public Pair(double probability, int node) {
        this.probability = probability;
        this.node = node;
    }

    public int compareTo(Pair pair2) {
        if (this.probability == pair2.probability) {
            return this.node - pair2.node;
        } else {
            return this.probability - pair2.probability > 0 ? -1 : 1;
        }
    }
}

cpp 解法, 执行用时: 156 ms, 内存消耗: 65.2 MB, 提交时间: 2023-09-26 20:13:55

class Solution {
public:
    // Djikstra 算法
    double maxProbability(int n, vector<vector<int>>& edges, vector<double>& succProb, int start, int end) {
        vector<vector<pair<double, int>>> graph(n);
        for (int i = 0; i < edges.size(); i++) {
            auto& e = edges[i];
            graph[e[0]].emplace_back(succProb[i], e[1]);
            graph[e[1]].emplace_back(succProb[i], e[0]);
        }

        priority_queue<pair<double, int>> que;
        vector<double> prob(n, 0);

        que.emplace(1, start);
        prob[start] = 1;
        while (!que.empty()) {
            auto [pr, node] = que.top();
            que.pop();
            if (pr < prob[node]) {
                continue;
            }
            for (auto& [prNext, nodeNext] : graph[node]) {
                if (prob[nodeNext] < prob[node] * prNext) {
                    prob[nodeNext] = prob[node] * prNext;
                    que.emplace(prob[nodeNext], nodeNext);
                }
            }
        }
        return prob[end];
    }
};

上一题