题目1 : 最小生成树三·堆优化的Prim算法

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

回到两个星期之前,在成功的使用Kruscal算法解决了问题之后,小Ho产生了一个疑问,究竟这样的算法在稀疏图上比Prim优化之处在哪里呢?

提示:没有无缘无故的优化!

输入

每个测试点(输入文件)有且仅有一组测试数据。

在一组测试数据中:

第1行为2个整数N、M,表示小Hi拥有的城市数量和小Hi筛选出路线的条数。

接下来的M行,每行描述一条路线,其中第i行为3个整数N1_i, N2_i, V_i,分别表示这条路线的两个端点和在这条路线上建造道路的费用。

对于100%的数据,满足N<=10^5, M<=10^6,于任意i满足1<=N1_i, N2_i<=N, N1_i≠N2_i, 1<=V_i<=10^3.

对于100%的数据,满足一定存在一种方案,使得任意两座城市都可以互相到达。

输出

对于每组测试数据,输出1个整数Ans,表示为了使任意两座城市都可以通过所建造的道路互相到达至少需要的建造费用。

样例输入
5 29
1 2 674
2 3 249
3 4 672
4 5 933
1 2 788
3 4 147
2 4 504
3 4 38
1 3 65
3 5 6
1 5 865
1 3 590
1 4 682
2 4 227
2 4 636
1 4 312
1 3 143
2 5 158
2 3 516
3 5 102
1 5 605
1 4 99
4 5 224
2 4 198
3 5 894
1 5 845
3 4 7
2 4 14
1 4 185
样例输出
92分析:之前弄了好长时间,看了好多材料也没搞懂怎么优化prim。今天在操作系统课上,不小心走神了。于是乎,只花了几分钟就想出来了到底要怎么优化。之前看别人的博客什么的,感觉很复杂。现在把我的想法写出来:堆优化prim算法:首先我们先想,之前在写prim的时候需要这样做,从当前的生成树开始,遍历所有可以抵达当前生成树的边,找到一条最短的边,将该边的权值加到生成树的权值总和上,加该点标记访问,并加到生成树上来。现在如果我们可以优化方法找到那条最短边的话,那复杂度不就降低了。怎么优化呢?之前的做法是用一个数组保存每个节点到生成树的距离,每次找的过程都要遍历一次这个数组。现在我们用一个优先队列(小根堆)来保存所有可以抵达生成树的边,每次只要取出该队列的最前面的且合法的边加到生成树上来就醒了。不合法的边会在这个过程中丢弃!有图有文字的描述过程如下:

代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <iostream>
#include <string>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#include <algorithm>
#define LL long long int
#define N 100000+10 //最大节点数
#define M 1000000+10 //最大的边数
#define MOD 142857
//N<=10^5, M<=10^6using namespace std;
int n, m;
struct node
{int v, w;bool operator<(const node &dd)const{return w>dd.w;} //权值小的优先
};
vector<node>q[N];
bool vis[N];
//堆优化的prim算法
LL ans;void queue_prim()
{//以节点1为起点进行扩展安全边 生成最小树priority_queue<node>que;while(!que.empty())que.pop(); //初始化清空优先队列 维护一个小根堆//这样每次找安全边的速度就提高了ans = 0;memset(vis, false, sizeof(vis));for(int i=0; i<q[1].size(); i++){que.push(q[1][i]); //将起点的所有连接边全部加入队列中来}vis[1]=true;int edge=n-1;//边数node cur;while(edge--){cur = que.top();que.pop();//这个地方需要注意一下//并不是每个从优先队列取出来的边都是可以加到生成树上去的if(vis[cur.v]==true){while(vis[cur.v]){cur=que.top(); que.pop();}}ans = ans+cur.w; //printf("%d--  ", cur.w );vis[cur.v]=true; //加入生成树的该点将被标记访问for(int i=0; i<q[cur.v].size(); i++){if(vis[ q[cur.v][i].v ]==false) //当前加入生成树的点可以扩充出的边指向的节点que.push(q[cur.v][i]);//如果没有被访问才会加入到队列当中来}}
}int main()
{scanf("%d %d", &n, &m);int i, j;int u, v, w;node cur;for(i=0; i<=n; i++)q[i].clear();for(i=0; i<m; i++){scanf("%d %d %d", &u, &v, &w);cur.v=v; cur.w=w;q[u].push_back(cur);cur.v=u;q[v].push_back(cur); //建立双向边}queue_prim();printf("%lld\n", ans );return 0;
}

 

转载于:https://www.cnblogs.com/yspworld/p/4546098.html

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

  1. 左耳听风 第二十九周

    左耳听风 第二十九周 每周完成一个ARTS: 每周至少做一个 leetcode 的算法题.阅读并点评至少一篇英文技术文章.学习至少一个技术技巧.分享一篇有观点和思考的技术文章.(也就是 Algorit ...

  2. C语言编程>第二十五周 ③ 下列给定程序中,函数fun的功能是:根据输入的三个边长(整型值),判断能否构成三角形;构成的是等边三角形,还是等腰三角形。若能构成等边三角形函数返回3,若能构成……

    例题:下列给定程序中,函数fun的功能是:根据输入的三个边长(整型值),判断能否构成三角形:构成的是等边三角形,还是等腰三角形.若能构成等边三角形函数返回3,若能构成等腰三角形函数返回2,若能构成三角 ...

  3. 三级pc技术_第十九周PC、笔电、数码周边新品汇总:AMD英特尔激战正酣

    [dogkeji-科技犬] 各位网友周末好,又到了2020年第十九周的PC.笔电.数码周边新品发布汇总时刻(2020年5月4日至2020年5月9日),那么本周有那些PC.笔电.数码周边新品发布呢?通过 ...

  4. 第二十九章:学校招生

    第二十九章:学校招生 李丽质突然忘记了这一茬子了,这些人还都不会化学方程式,李丽质想到后世的化学教学方式,于是他便对着众人说道:"这我会举办一个化学学校的,专门教授你们化学知识的." ...

  5. C语言编程>第二十二周 ④ 从键盘输入一组小写字母,保存在字符数组str中,请补充fun函数,该函数的功能是:把字符数组str中字符下标为偶数的小写字母转换成对应的大写字母,结果仍保存在原数组

    例题:从键盘输入一组小写字母,保存在字符数组str中,请补充fun函数,该函数的功能是:把字符数组str中字符下标为偶数的小写字母转换成对应的大写字母,结果仍保存在原数组中. 例如,输入 " ...

  6. C语言编程>第二十二周 ⑥ 请补充fun函数,该函数的功能是:把字符下标能被2和3同时整除的字符从字符串s中删除,把剩余的字符重新保存在字符串s中。

    例题:请补充fun函数,该函数的功能是:把字符下标能被2和3同时整除的字符从字符串s中删除,把剩余的字符重新保存在字符串s中.字符串s从键盘输入,其长度作为参数传入fun函数. 例如,输入 " ...

  7. 第十九周学习周报(20180709-20180715)

    第十九周学习周报 一.本周学习情况 1.学习了李宏毅老师的深度学习课程 2.跑了识别猪的模型 二.学习笔记      在生成lmdb过程中,出现路径错误,将文件的路径换成绝对路径再尝试. cv2.Ve ...

  8. C语言编程>第二十二周 ③ 下列给定的程序中,函数fun的功能是根据整型形参n,计算如下公式的值:

    例题:下列给定的程序中,函数fun的功能是根据整型形参n,计算如下公式的值: 例如,若n=1000,则应输出0.000155. 注意:不要改动main函数,不能增行或删行,也不能更改程序的结构. 代码 ...

  9. Python-opencv学习第二十九课:高斯双边模糊

    Python-opencv学习第二十九课:高斯双边模糊 文章目录 Python-opencv学习第二十九课:高斯双边模糊 一.学习部分 二.代码部分 1.引入库 2.读入数据 3.完整代码 三.运行结 ...

  10. C语言编程>第二十五周 ① 给定程序中,函数fun的功能是:在形参s所指字符串中的每个非数字字符之后插入一个“*”号。

    例题:给定程序中,函数fun的功能是:在形参s所指字符串中的每个非数字字符之后插入一个"*"号. 例如,形参s所指的字符串为:albc45sdtg56f,则执行结果为:a*1b*c ...

最新文章

  1. 18岁双料竞赛金牌得主邓明扬:我只是数学初学者,求在MIT“活”下去
  2. wstring与string相互转换
  3. vscode中装js解释器_h5学习记录(1)--vscode配置js开发环境
  4. VisualBox中增大linux硬盘空间的方法
  5. Docker 学习应用篇之一: 初识Docker
  6. 【Linux】一步一步学Linux——groupadd命令(87)
  7. 解决在Win2008下IIS7不显验证码的问题
  8. kubeadm安装kubernetes 1.13.2多master高可用集群
  9. 请教设计模式大牛们几点
  10. 获取手机唯一标识插件_非常强大的几款手机浏览器,适用于某些黑科技功能
  11. 固定数组实现一个队列
  12. 网络是怎样连接的学习笔记1----探索浏览器内部(十分适合理清思路)
  13. 苹果cms码支付接口
  14. U转串口时,鼠标乱动,解决办法
  15. win7升级win10后出现VisualSVN Server提供程序无法执行所尝试的操作 0x80041024
  16. Redis-入门学习笔记
  17. 超轻型飞机 - 蟋蟀,世界上最小的双引擎载人飞机!
  18. html 水平分割,HTML设置水平分割线
  19. 文旅夜游项目如何做好景区内容建设
  20. [易语言] 百宝云+迅雷引擎:满速、直链下载文件!

热门文章

  1. Mac 系统下 配置多个ssh-key (git sourcetree)
  2. CentOS 7.5 重置 root 密码
  3. 10)Thymeleaf 标记选择器语法
  4. HTML5 音频 / 视频 DOM 操作
  5. 阶段5 3.微服务项目【学成在线】_day04 页面静态化_05-freemarker基础-List指令
  6. Java异常处理之------Java方法中throws Exception使用案例!什么情况下使用throws Exception?...
  7. 仅当使用了列列表并且 IDENTITY_INSERT 为 ON 时,才能为表't_ArticleFiles'中的标识列指定显式值。...
  8. OpenCASCADE 开发框架(一)
  9. LoggingFilter Session 以及Async
  10. array_filter()用法