emm,在这里给大家推荐两个方法,一个是我比赛的时候写的堆优化版本的dijkstra,和求最短路径的spfa算法。一般写题的时候都不是接口型的OJ,而leetcode上的oj是接口型的,所以遇到一些些大大小小的问题,一直耽搁了快一个小时,本来就起晚了,AC完这道题也就刚刚结束。
看完排名前面大佬们写的dijkstra用的临界矩阵建图只写了30多行,而我的堆优化版的dijkstra写了70多行,才知道差距,中间有很多不足的地方。
我们这里用两种建图的Dijkstra实现这道题。

注:其实堆优化的Dijkstra就是Dijkstra+优先级队列,可以使得你的时间复杂度优化到O(nlgn),所以 堆优化版的dijkstra = dijkstra + 优先级队列
如同最小生成树Kruskal 算法就是 并查集 + 排序 + 选择 一样。

leetcode周赛第3题 概率的最大路径

题目地址: 这里!

题目描述

给你一个由 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. 拨开题目要求,探讨这道题的本质,确定是最短路径的相关题目。确定大致算法,Dijkstra算法,Floyed算法,spfa算法,堆优化的Dijkstra算法,然后看这道题的数据范围n = 10^4 ,好,我们排除Floyed算法(O(n3)),然后感觉一下,O(n2)有可能也会超时,我们将Floyed也先排除,实际上真的超时了。所以现在我们的算法只有 堆优化的Dijkstra算法,和Spfa算法。但是Spfa的时间复杂度为O(nm), m是边数,这里的边数是2*10^4有可能也难顶。(但是我最后试了试发现可以过)。
  2. 然后就是一般的建图流程,我采用的是邻接表建图。因为是无向边,所以要建双向的路径。
  3. 注意这里的优先级队列是大根堆的,每一次从队列中去更新其它的边的概率要选择概率最大的去更新其点的概率。
  4. 起始点的概率初始化为1.0,然后通过大根堆去不断的更新其它点的最大概率即可。
  5. 题目中坑的地方,一开始我不知道这里的n要取多大,所以就全部按照const int N = 1e4 + 20,来算,实际上这里的n已经告诉你了,第一个参数n的含义就是 城市的多少,我把它看成了 edges的大小(路径的条数了),实际上不是,所以一直报一些堆溢出的错误,难改的一批,调试了半天,直到自己试了一些条件的测试用例,才发现错误。实际上不需要定义那些的N,可以完全使用参数中给的n。

为什么这里要建大根堆,这里再次说明一下吧:
大根堆的堆顶是堆中最大值,小根堆的堆顶是堆中最小值。
在这里我们不是要求点和点之间的最大概率,你第一个节点从优先级队列中出来,是要更新别的点到第一个点的最大概率,如果建小堆,第一个出来的节点会很小,也是要更新其它点的最大概率,建大堆的目的是不是因为有可能建小堆一开始出来的点小,会把最大距离更新的更小。

堆优化版本Dijkstra的代码实现:

const int N = 1e4 + 20;
const int M = 1e5;
class Solution {public:double dis[N];int h[N], ne[M], e[M];int idx = 0;double w[M];bool st[N];typedef pair<double, int> PII;void add(int a, int b, double c){e[idx] = b;ne[idx] = h[a];w[idx] = c;h[a] = idx++;}void dijkstra(int start, int end){memset(dis, 0, sizeof dis);memset(st,false,sizeof st);priority_queue<PII, vector<PII>, less<PII>> pq; //大根堆的dis[start] = 1.0;pq.push({ dis[start], start });while (pq.size()){auto tmp = pq.top();pq.pop();int ver = tmp.second;double distance = tmp.first;if (st[ver]) continue;st[ver] = true;for (int i = h[ver]; i != -1; i = ne[i]){int j = e[i];if (dis[j] < dis[ver] * w[i]){dis[j] = dis[ver] * w[i];pq.push({ dis[j], j });}}}}double maxProbability(int n, vector<vector<int>>& edges, vector<double>& succProb, int start, int end) {// double g[N][N];memset(h, -1, sizeof h);memset(ne, 0, sizeof ne);memset(e, 0, sizeof e);for (int i = 0; i < edges.size(); i++){int a = edges[i][0];int b = edges[i][1];add(a, b, succProb[i]);add(b, a, succProb[i]);}dijkstra(start, end);return dis[end];}
};

有可能这里没有算考试的时候的人做的,而我这种方法提交的在前面的原因吧。当然还有一群大佬们是有bfs做的。

堆优化版本Dijkstra邻接矩阵的代码实现:


const double eps = 1e-8;
class Solution {public:double maxProbability(int n, vector<vector<int>>& edges, vector<double>& succProb, int start, int end) {vector<double> dis(n);dis[start] = 1;vector<vector<pair<int,double>>> vvp(n);for(int i = 0; i < edges.size(); i++){int u = edges[i][0];int v = edges[i][1];double p = succProb[i];vvp[u].push_back({v,p});vvp[v].push_back({u,p});}priority_queue<pair<double,int>> pq;pq.push({dis[start],start});vector<bool> vis(n);while(pq.size()){auto tmp = pq.top();int u = tmp.second;double p = tmp.first;pq.pop();if(vis[u])continue;vis[u] = true;if(p < eps)continue;for(auto edge:vvp[u]){int v = edge.first;double now  = p * edge.second;if(dis[v] < now){dis[v] = now;pq.push({dis[v],v});}}}return dis[end];}
};

关于Spfa改日 再补吧。

这次A了三道题 hah,还是菜,加油吧!欠的太多,出来混是要还的啊。

leetcode第197场周赛 之 5211概率的最大路径相关推荐

  1. LeetCode 第 197 场周赛(468/5273,前8.88%)

    文章目录 1. 比赛结果 2. 题目 1. LeetCode 5460. 好数对的数目 easy 2. LeetCode 5461. 仅含 1 的子串数 medium 3. LeetCode 5211 ...

  2. LeetCode第 227 场周赛题解

    LeetCode第 227 场周赛题解 检查数组是否经排序和轮转得到 原题链接 https://leetcode-cn.com/problems/check-if-array-is-sorted-an ...

  3. LeetCode 第 194 场周赛

    LeetCode 第 194 场周赛 数组异或操作 思路和代码 保证文件名唯一 思路及代码 避免洪水泛滥 思路及代码 找到最小生成树里的关键边和伪关键边 思路及代码 这次周赛比以往难很多. 数组异或操 ...

  4. LeetCode第187场周赛(Weekly Contest 187)解题报告

    差点又要掉分了,还好最后几分钟的时候,绝杀 AK.干巴爹!!! 第一题:思路 + 模拟暴力. 第二题:线性扫描. 第三题:双指针(滑动窗口) + 优先队列. 第四题:暴力每一行最小 k 个 + 优先队 ...

  5. Acwing第72场周赛+Leetcode第314场周赛

    Acwing第72场周赛 第一题:AcWing 4624. 最小值 分析:向下取整可以用到math.h头文件中的floor()函数,最后输出时套用两个min()函数求三个数的最小值即可. 代码: #i ...

  6. Leetcode第 310 场周赛 补打

    Leetcode 第310场周赛 自己赛后打了一下,记录了一下时间,大概15min A 3题,第四题是写不出来,然后学习了一天线段树(真的强). 思路: 1.排序后统计偶数的数目 2.遍历扫一遍,用直 ...

  7. LeetCode第176场周赛(Weekly Contest 176)解题报告

    又是一周掉分之旅,我发现,LeetCode周赛的数据好水,所以有的时候,实在没思路,先暴力解决试试(即使分析出时间复杂度会超时),比如第二题和第三题都可以暴力通过,GG思密达. 这周主要使用了数据结构 ...

  8. Leetcode第321场周赛补题

    Leetcode第321场周赛补题 第一题:6245. 找出中枢整数 - 力扣(LeetCode) 分析:由于数组中是差值为1的等差数列,所以可以直接用等差数列求和公式的朴素法更加简便的解决这题,,其 ...

  9. 【JAVA】力扣第197场周赛代码+解题思路

    目录 5460. 好数对的数目 解题锦囊 思路一:常规(未用解题锦囊) 代码 思路二:使用解题锦囊 5461. 仅含 1 的子串数 解题锦囊 代码 错误点 5211. 概率最大的路径 解题锦囊 代码 ...

  10. [算法]LeetCode第194场周赛202006021

    第194场周赛 20200621 1486. 数组异或操作 题目描述1 给你两个整数,n 和 start . 数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 ...

最新文章

  1. Android精通:View与ViewGroup,LinearLayout线性布局,RelativeLayout相对布局,ListView列表组件...
  2. [luogu2576 SCOI2010] 幸运数字 (容斥原理)
  3. 【AI初识境】给深度学习新手开始项目时的10条建议
  4. ASP.NET Performance Monitoring, and When to Alert Administrators
  5. 1.2.3 TCP/PI参考模型(应用层、传输层、网际层、网络接口层)、五层参考模型(应用层、传输层、网络层、数据链路层、物理层)、OSI与TCP/IP参考模型比较
  6. App设计灵感之十二组精美的机票预订App设计案例
  7. Python---时间函数
  8. python中的替换函数_python:替换模块类中的函数
  9. Ext JS学习第二天 我们所熟悉的javascript(一)
  10. Spring核心——MessageSource实现国际化
  11. Oracle中文简繁体转换函数
  12. java每日一练(19_03_18)
  13. std::uninitialized_copy::_Unchecked_iterators::_Deprecate
  14. 医药行业大拼杀 小药药、药聚汇、朗致集团医药、同仁堂,模式对比
  15. ai 计算机视觉_人工智能中的计算机视觉
  16. 六顶思考帽(edward de bono)
  17. 植物大战僵尸针对关卡地址以及全部关数的内存基址详细步骤~包含如何观察地址情况等
  18. 搜狗蜘蛛池之搜狗泛站群技巧详解
  19. 2的负x次幂图像_函数y=2的x次方与y=x的2次方的图象的 – 手机爱问
  20. 水果店要什么设备,开水果店的设备

热门文章

  1. If(flag) 与 if(!flag)
  2. 【3D目标检测】open3D安装与使用
  3. 解决win10微软应用商店打不开的问题
  4. Android Room 数据访问对象(DAO)详解
  5. android 文件传输 无法复制,Win10坑死安卓!MTP连接大BUG:无法复制、丢文件
  6. 助你迈向成功之路的二十二个好习惯
  7. y等于根号x用c语言程序表示出来,c语言描述x和y都大于或等于z的表达式是
  8. orcal添加序列让主键的自动增长
  9. usb摄像头android录像软件,USB摄像头app
  10. 猛文:关于中国歼20气动性能…