原理简介
Dijkstra作为一种求解单元最短路的算法,其本质是贪心的,他保证了当前将要加入到已经求解出最短路的点集合S的点到源点的距离,一定是小于后面加入的所有点的。
问题引入
概率最大路径
分析:
该题中所求的概率最大路,具有dijkstra求解的单元最短路的特性,因为概率乘法是单调递减的,意味着Dijkstra算法中求解过程中,先确定最短路的点,一定会比后面的概率大,也即满足贪心的性质,只要我们已经求出某一点的概率最大路径, 那么后面不可能再产生到该点概率更大的路径。
算法实现
dijstra实现:
class Solution {
public:
double maxProbability(int n, vector<vector<int>>& edges, vector<double>& succProb, int start, int end) {
vector<double> pro(n,0);
vector<vector<pair<double,int> >> g(n);
int len=edges.size();
for(int i=0;i<len;i++){
g[edges[i][0]].emplace_back(succProb[i],edges[i][1]);
g[edges[i][1]].emplace_back(succProb[i],edges[i][0]);
}
priority_queue<pair<double,int>> que;
que.emplace(1,start);
vector<bool> tip(n,false);
pro[start]=1;
for(;!que.empty();){
int k=que.top().second;
que.pop();
if(tip[k]){
continue;
}
if(k==end){
return pro[end];
}
for(int j=0;j<g[k].size();j++){
if(pro[g[k][j].second]<pro[k]*g[k][j].first){
pro[g[k][j].second]=pro[k]*g[k][j].first;
que.emplace(pro[g[k][j].second],g[k][j].second);
}
}
tip[k]=true;
}
return pro[end];
}
};
要注意的是我们可以使用priority_queue来优化时间,使得得到下一个将要求出最短距离的点的时间复杂度为logn。其次由于图是稀疏的,所以一定要用领接链表来存储图,而不是领接矩阵。