dijkstra(最短路)和Prim(最小生成树)下的堆优化
dijkstra(最短路)和Prim(最小生成树)下的堆优化
最小堆:
down(i)【向下调整】:从第k层的点i开始向下操作,第k层的点与第k+1层的点(如果有)进行值大小的判断,如果父节点的值大于子节点的值,则修改,并继续对第k+1层与第k+2层的点进行判断和修改,否则不修改,且退出。当点向下移动到树的最后一层,没有子节点供判断与修改,停止操作。
树最多有log(n) 层[log(n)=log2n,一般省略数字2],时间复杂度log(n)次。
up(i)【向上调整】:同理,时间复杂度log(n)次。
1.求n个数进行排序:
I.建树(n/2次down):
for i←n/2 downto 1 do down(i)
II.取数(n次down):
for i←1 to n do
temp←a[1];
a[1]←a[n];
a[n]←temp;
n←n-1;
down(1);
所以时间复杂度:O(nlogn)
2.dijkstra , prim 需要修改数,取数多少次?
I.dijkstra:
从点x出发到点y(或其它剩余点)的最短路:
dist[t]:点t到点x的最短距离,若点t不能到达点x,则值为无穷(设为一个足够大的值,如2000000000)。初始时dist[x]=0,其它点dist[]=无穷。
初始:d=x。
1.遍历所有与点d相关联的边,修改与d点相邻的点的最短距离(到x点)。
2.在未执行1操作的点中找到最短距离(到x点)的点d。
3.重复1,2操作,直到2操作d=y,或者执行n-1次(总共n个点,那么求的是从x点到其它点的最短路)。
时间复杂度:
最多执行n-1次操作,而操作1,2时间复杂度O(n),时间复杂度O(n^2)。
堆优化:
初始时,把所有的dist[k](k=1,2,……,n)建最小堆。对于操作1,修改堆中某些数(dist[])的值,并对这些数的位置进行修改(距离是越来越短,所以进行向上调整);
对于操作2,把堆中第一个数(最小值)取出,删除根结点,把最后一个元素作为根结点,然后对根节点进行向下调整,保证调整后的根节点为树中的最小点。
时间复杂度:
建堆n个数,时间复杂度O(nlogn)
取数n-1次,而堆中节点个数总小于等于n(最多有n个dist[]),时间复杂度O(nlogn)。
最坏的情况:
如下图(可删去部分边),与点k相邻的边(边另外的点的编号小于k)的长度为k,求从n点出发到y点,从点n出发到点1,则所有的边都会被修改为dist[]的值一次,修改e次,则时间复杂度O(eloge),其中e为边的数目。

总时间复杂度O(nlogn+elogn)。
若图是稠密图,e很大,如n<=10000,而e<=n*(n-1)/2,若e= n*(n-1)/2,nlogn+elogn <664452058,而n*n=100000000,则该优化比原来时间复杂度还高不少。
若图是稀疏图,e不大,如n<=10000,e<=100000,则elogn<1328772,n*n=100000000,此时用该优化不会超时而用原方法会超时。
更好的优化:斐波那契堆(不涉及删除元素的操作仅需O(1)的平摊运行时间)
取数n-1次(删除+修改),而堆中节点个数总小于等于n(最多有n个dist[]),时间复杂度O(nlogn)。
修改e次数值,时间复杂度O(e)。
总时间复杂度:O(nlogn+e)。
II.Prim:
求最小生成树
dist(t):点t到集合S中的点的最短距离,该最短距离为其中一条边的长度,若点t不能到达任意一个点,则值为无穷(设为一个足够大的值,如2000000000)。初始时dist[x]=0,其它点dist[]=无穷。
从任意一个点x出发,初始:d=x,S=空集【S为集合】,T=全集。
1.S=S+{d},T=T-{d},遍历所有与点d相关联的边,修改集合T中的点的dist值。
2.从点T中找到dist[]值最小对应的点d,图添加一条边,该边的长度为dist[d]。可以添加一个变量记录边的另外一个点。
3.重复1,2操作,直到执行n-1次(即添加n-1条边)。
时间复杂度:最多执行n-1次操作,而操作1,2时间复杂度O(n),时间复杂度O(n^2)。
堆优化:
初始时,把所有的dist[k](k=1,2,……,n)建最小堆。对于操作1,修改堆中某些数(dist[])的值,并对这些数的位置进行修改(距离是越来越短,所以进行向上调整);
对于操作2,把堆中第一个数(最小值)取出,删除根结点,把最后一个元素作为根结点,然后对根节点进行向下调整,保证调整后的根节点为树中的最小点。
时间复杂度:同理总时间复杂度O(nlogn+elogn)。
斐波那契堆优化:O(nlogn+e)。
另外的方法(不一样的角度):
dist(t):点t到集合S中的点的最短距离,该最短距离为其中一条边的长度,若点t不能到达任意一个点,则值为无穷(设为一个足够大的值,如2000000000)。初始时dist[x]=0,其它点dist[]=无穷。
从任意一个点x出发,初始:d=x,S=空集【S为集合】,T=全集。R=空集。
1.S=S+{d},T=T-{d},遍历所有与点d相关联的边,若某条边的另外一个点在T集合而不是在S集合,则把该边加入集合R中。
2.从集合R中找到长度最小的且边有一个点在T集合(边的另外一个点必在S集合)的边,d=边的两点中的在T集合的点。图添加一条边,该边的长度为dist[d]。可以添加一个变量记录边的另外一个点。
3.重复1,2操作,直到执行n-1次(即添加n-1条边)。
堆优化:
把边加入堆中,时间复杂度O(eloge)。
取边n-1次,时间复杂度O(nloge)。
[事实上每次堆的数目小于等于e]
总时间复杂度O(nloge+eloge)。
无疑,该方法比上述方法时间复杂度要高。
c++用优先队列更好,见:
http://www.cnblogs.com/cmyg/p/8725042.html
dijkstra(最短路)和Prim(最小生成树)下的堆优化的更多相关文章
- prim最小生成树算法(堆优化)
prim算法原理和dijkstra算法差不多,依然不能处理负边 1 #include<bits/stdc++.h> 2 using namespace std; 3 struct edge ...
- POJ 3635 - Full Tank? - [最短路变形][手写二叉堆优化Dijkstra][配对堆优化Dijkstra]
题目链接:http://poj.org/problem?id=3635 题意题解等均参考:POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]. 一些口胡: ...
- NEU 1664 传送(最短路基础 堆优化Dijkstra)
题目描述 小A最近喜欢上一款游戏:游戏把地图分了一些区域,这些区域可能会重叠,也可能不会. 游戏中有一项传送技能,改传送技能只能将在同一区域的两个地方使用.小A可以利用区域中重叠部分来实现从某一区域到 ...
- Luogu 3953[NOIP2017] 逛公园 堆优化dijkstra + 记忆化搜索
题解 首先肯定是要求出单源最短路的,我用了堆优化dijikstra ,复杂度 mlogm,值得拥有!(只不过我在定义优先队列时把greater 打成了 less调了好久 然后我们就求出了$i$到源点的 ...
- 堆优化dijkstra
单源最短路径 题目链接:https://www.luogu.org/problemnew/show/P4779 直到做了这个题才发现我之前写的堆优化dijkstra一直是错的.. 这个堆优化其实很容易 ...
- Prim 最小生成树算法
Prim 算法是一种解决最小生成树问题(Minimum Spanning Tree)的算法.和 Kruskal 算法类似,Prim 算法的设计也是基于贪心算法(Greedy algorithm). P ...
- Dijkstra最短路算法
Dijkstra最短路算法 --转自啊哈磊[坐在马桶上看算法]算法7:Dijkstra最短路算法 上节我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最 ...
- 一步一步写算法(之prim算法 下)
原文:一步一步写算法(之prim算法 下) [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 前两篇博客我们讨论了prim最小生成树的算法,熟悉 ...
- 【坐在马桶上看算法】算法7:Dijkstra最短路算法
上周我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短路”.本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径 ...
随机推荐
- 手机APP自动化之uiautomator2 +python3 UI自动化
题记: 之前一直用APPium直到用安卓9.0 发现uiautomatorviewer不支持安卓 9.0,点击截屏按钮 一直报错,百度很久解决方法都不可以,偶然间看见有人推荐:uiautomator ...
- 自动化批量管理工具salt-ssh - 运维小结
根据以往运维工作中操作经验来说,当管理上百台上千台服务器时,选择一款批量操作工具是及其有必要的.早期习惯于在ssh信任关系的前提下做for;do;done循环语句的批量操作,后来逐渐趋于使用批量工具操 ...
- python之requests
发送请求 导入 Requests 模块: >>> import requests >>> r = requests.get('https://xxxxxxx.jso ...
- 基于SSH框架开发的《高校大学生选课系统》的质量属性的实现
基于SSH框架开发的<高校大学生选课系统>的质量属性的实现 对于可用性采取的是错误预防战术,即阻止错误演变为故障:在本系统主要体现在以下两个方面:(1)对于学生登录模块,由于初次登陆,学生 ...
- 探索guava(一)——前置条件Preconditions类
作用 可以简洁的完成参数检验,在进行业务逻辑代码前进行前置判断.并且避免了冗长的if语句.guava将所有检验的API都放置于Preconditions类中. API Preconditions类大致 ...
- CSS里Postion几个取值relative、absolute、static、fixed的区别和用法
---恢复内容开始--- static:静态定位,也是postion的默认值,没有定位,元素出现在正常的流中,忽略top\bottom\left\right或者z-index声明. relative: ...
- 业务-----添加Service常用逻辑
1.参数不能为空 /** * 添加人员时判断是否字段全部传值 * @param request * @return */ private Boolean checkClientByCols(Clien ...
- laravel5 报错419,form 添加crrf_field 后让然失败,本地环境配置问题
这个是因为laravel自带CSRF验证的问题 解决方法 方法一:去关掉laravel的csrf验证,但这个人不建议,方法也不写出来了. 方法二:把该接口写到api.php上就好了 方法三: 首先在页 ...
- CIO知识储备
1.IT安全和法规知识是CIO的首要 2.IT项目管理专业知识是CIO的必备 3.合作伙伴管理和供应商管理对成功也很关键 4.企业数据管理技能对CIO越来越重要 5.企业财务技能是CIO的一种必备 6 ...
- shell 学习笔记二
一.break命令 break命令允许跳出所有循环(终止执行后面的所有循环). 下面的例子中,脚本进入死循环直至用户输入数字大于5.要跳出这个循环,返回到shell提示符下,就要使用break命令. ...