关于Prim的堆优化

Prim的算法的具体思路是从某个点开始用贪心的策略向外扩展,找到离当前生成树最近的节点加入树中,并用该节点更新生成树到其他节点的距离。显然复杂度O(n^2),而且有一个二倍的常数(一共扩展n次,每次找最近的点是O(n)的,用该点更新其它点在稠密图时也是O(n)的)。

然后某些大佬就想到可以用堆维护当前生成树到各个节点的距离,然而其实这并不会快多少

首先我们假设是个稠密图(稀疏图尽量用kruskal),一共有n个节点要加入生成树中,每个节点加入时又要更新生成树到与之相连的点的距离,我们只是在找离生成树最近的节点时才用到了堆,所以理想复杂度为O(n*(n+logn)),其实也就是O(n^2)。然后我们考虑堆中并不是只有n个节点(因为一个点可以重复入堆多次),所以最坏情况下堆中可能有接近(n^2/2)个节点,再加上堆的常数,就一点优势都没有了。

总结,求最小生成树时稠密图用prim,且无需堆优化,稀疏图时能用kruskal就用,否则再考虑堆优化prim

原文地址:https://www.cnblogs.com/zub23333/p/8457047.html

时间: 2024-10-27 02:45:03

关于Prim的堆优化的相关文章

hiho一下 第二十九周 最小生成树三·堆优化的Prim算法【14年寒假弄了好长时间没搞懂的prim优化:prim算法+堆优化 】

题目1 : 最小生成树三·堆优化的Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 回到两个星期之前,在成功的使用Kruscal算法解决了问题之后,小Ho产生了一个疑问,究竟这样的算法在稀疏图上比Prim优化之处在哪里呢? 提示:没有无缘无故的优化! 输入 每个测试点(输入文件)有且仅有一组测试数据. 在一组测试数据中: 第1行为2个整数N.M,表示小Hi拥有的城市数量和小Hi筛选出路线的条数. 接下来的M行,每行描述一条路线,其中第i行为3个整数N1_

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)

hihoCoder #1109 最小生成树之堆优化的Prim算法

原题地址:http://hihocoder.com/problemset/problem/1109 #1109 : 最小生成树三·堆优化的Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 回到两个星期之前,在成功的使用Kruscal算法解决了问题之后,小Ho产生了一个疑问,究竟这样的算法在稀疏图上比Prim优化之处在哪里呢? 提示:没有无缘无故的优化! 输入 每个测试点(输入文件)有且仅有一组测试数据. 在一组测试数据中: 第1行为2个整数N.M,表示小

hihoCoder_#1109_堆优化的Prim算法

#1109 : 最小生成树三·堆优化的Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 回到两个星期之前,在成功的使用Kruscal算法解决了问题之后,小Ho产生了一个疑问,究竟这样的算法在稀疏图上比Prim优化之处在哪里呢? 提示:没有无缘无故的优化! 输入 每个测试点(输入文件)有且仅有一组测试数据. 在一组测试数据中: 第1行为2个整数N.M,表示小Hi拥有的城市数量和小Hi筛选出路线的条数. 接下来的M行,每行描述一条路线,其中第i行为3个整数N

P3366 【模板】最小生成树(堆优化prim)

堆优化prim 复杂度大概O(nlogn) #include<cstdio> #include<cstring> #include<queue> using namespace std; struct data{ int d,u; bool operator < (const data &tmp) const {return d>tmp.d;} }e[400002]; priority_queue <data> h; bool vis[5

图论——最小生成树prim+邻接表+堆优化

今天学长对比了最小生成树最快速的求法不管是稠密图还是稀疏图,prim+邻接表+堆优化都能得到一个很不错的速度,所以参考学长的代码打出了下列代码,make_pair还不是很会,大体理解的意思是可以同时绑定两种元素(和struct差不多)但加入堆的时候以第一个元素来进行优先队列,建立的是大根堆由于每次要选出最小的边所以把边取反,最小的那个边加上符号就变成最大的了,大体上就是这样.prim的思想. #include<iostream> #include<cstdio> #include&

dij+堆优化

写这个dij+堆优化的原因是有些地方卡SPFA,只能搞这个: 香甜的奶油: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<cstdlib> 6 #include<ctime> 7 #include<vector> 8 #include<algorithm> 9 #include&

[转]浅谈dijkstra堆优化

众所周知的,dijkstra是图论算法中求单源最短路的一种简单求法.可能有人会说SPFA比dijkstra要实用,而且可以用于求存在负边权的情况,但是dijkstra有着他的优点——其运行速度上优于SPFA. (PS.需要堆进行优化.) 我们先看一道经典(水)题: 平面上有n个点(n<=100),每个点的坐标均在-10000~10000之间.其中的一些点之间有连线. 若有连线,则表示可从一个点到达另一个点,即两点之间有通路,通路的距离为两点之间的直线距离.现在的任务是找出从入点到出点之间的最短路

Dij的堆优化

#include<algorithm> #include<iostream> #include<cstdio> #include<cstring> #include<queue> #define M 100000 #define pa pair<int,int>//优先比较第一个元素 using namespace std; int d[M],n,m,cnt,head[M],next[M],u[M],dis[M],num,s,t; b