hiho一下 第二十九周 最小生成树三·堆优化的Prim算法【14年寒假弄了好长时间没搞懂的prim优化:prim算法+堆优化 】
题目1 : 最小生成树三·堆优化的Prim算法
描述
回到两个星期之前,在成功的使用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^6 using 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;
}
hiho一下 第二十九周 最小生成树三·堆优化的Prim算法【14年寒假弄了好长时间没搞懂的prim优化:prim算法+堆优化 】的更多相关文章
- hihocoder hiho一下 第二十六周 最小生成树一·(Prim算法)
题目1 : 最小生成树一·Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可以拥 ...
- “全栈2019”Java多线程第二十九章:可重入锁与不可重入锁详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java第二十九章:数组详解(中篇)
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 大白话5分钟带你走进人工智能-第二十九节集成学习之随机森林随机方式 ,out of bag data及代码(2)
大白话5分钟带你走进人工智能-第二十九节集成学习之随机森林随机方式 ,out of bag data及代码(2) 上一节中我们讲解了随机森林的基本概念,本节的话我们讲解随机森 ...
- NeHe OpenGL教程 第二十九课:Blt函数
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- Gradle 1.12用户指南翻译——第二十九章. Checkstyle 插件
其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...
- SQL注入之Sqli-labs系列第二十九关(基于WAF防护的单引号报错注入)
开始挑战第二十九关(Protection with WAF) 0x1查看源码 (1)login.php页面存在防护,只要检测到存在问题就跳转到hacked.php页面(其他信息看备注) 0x2 for ...
- python第二十九课——文件读写(复制文件)
自定义函数:实现文件复制操作有形参(2个) 没有返回值相似版(不用) def copyFile(src,dest): #1.打开两个文件:1个关联读操作,1个关联写操作 fr=open(src,'rb ...
- python第二十九课——文件读写(读取读取中文字符)
演示:读取中文字符 结论: 1).如果不设置encoding,默认使用gbk进行编解码 2).如果编码和解码不一致,最终导致报错,但是一旦设置了errors='ingore',那么就不会报错,而采取乱 ...
随机推荐
- Https所涉及名词及相关后缀名解释
HTTPS: HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版.即 ...
- centos7 重启网卡报错
systemctl restart network 时候报错: rtnetlink answers file exists 是network和NetworkManager冲突了 一般建议直接 syst ...
- IDEA下配置Spring Boot的热部署
© 版权声明:本文为博主原创文章,转载请注明出处 devtools简介 spring-boot-devtools会监听classpath下的文件变动,并且会立即重启应用(发生在保存时机),因为其采用的 ...
- SVN服务端的安装搭建(Linux)
在CentOS下安装 SVN 大多数 GNU/Linux 发行版系统自带了Subversion ,所以它很有可能已经安装在你的系统上了.可以使用下面命令检查是否安装了. svn --version 如 ...
- [译]GLUT教程 - 整合代码7
Lighthouse3d.com >> GLUT Tutorial >> Extras >> The Code So Far VII 以下是子窗体的最终版本代码. ...
- ffmpeg截图
ffmpeg.exe -probesize 32768 -i "rtmp://localhost/live/1 live=1" -y -t 0.001 -ss 1 -f image ...
- LNMP环境搭建之php安装,wordpress博客搭建
LNMP环境搭建之php安装,wordpress博客搭建 一.介绍: 1.什么是CGI CGI全称是"通用网关接口"(Common Gateway Interface),HTTP服 ...
- 09 Memcached 分布式之取模算法的缺陷
一: Memcached 分布式之取模算法的缺陷(1)假设你有8台服务器,运行中突然down一台,则求余数的底数就7. 后果: key_0%8==0 ,key_0%7==0 =>hist(命中) ...
- JVM调优- jstat(转)
jstat的用法 用以判断JVM是否存在内存问题呢?如何判断JVM垃圾回收是否正常?一般的top指令基本上满足不了这样的需求,因为它主要监控的是总体的系统资源,很难定位到java应用程序. Jstat ...
- swift打印方法名文件路径
1.打印方法名 print(#function) 1.打印文件路径 print(#file)