题目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^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算法+堆优化 】的更多相关文章

  1. hihocoder hiho一下 第二十六周 最小生成树一·(Prim算法)

    题目1 : 最小生成树一·Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可以拥 ...

  2. “全栈2019”Java多线程第二十九章:可重入锁与不可重入锁详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  3. “全栈2019”Java第二十九章:数组详解(中篇)

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  4. 大白话5分钟带你走进人工智能-第二十九节集成学习之随机森林随机方式 ,out of bag data及代码(2)

              大白话5分钟带你走进人工智能-第二十九节集成学习之随机森林随机方式 ,out  of  bag  data及代码(2) 上一节中我们讲解了随机森林的基本概念,本节的话我们讲解随机森 ...

  5. NeHe OpenGL教程 第二十九课:Blt函数

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  6. Gradle 1.12用户指南翻译——第二十九章. Checkstyle 插件

    其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...

  7. SQL注入之Sqli-labs系列第二十九关(基于WAF防护的单引号报错注入)

    开始挑战第二十九关(Protection with WAF) 0x1查看源码 (1)login.php页面存在防护,只要检测到存在问题就跳转到hacked.php页面(其他信息看备注) 0x2 for ...

  8. python第二十九课——文件读写(复制文件)

    自定义函数:实现文件复制操作有形参(2个) 没有返回值相似版(不用) def copyFile(src,dest): #1.打开两个文件:1个关联读操作,1个关联写操作 fr=open(src,'rb ...

  9. python第二十九课——文件读写(读取读取中文字符)

    演示:读取中文字符 结论: 1).如果不设置encoding,默认使用gbk进行编解码 2).如果编码和解码不一致,最终导致报错,但是一旦设置了errors='ingore',那么就不会报错,而采取乱 ...

随机推荐

  1. xgboost 特征选择,筛选特征的正要性

    import pandas as pd import xgboost as xgb import operator from matplotlib import pylab as plt def ce ...

  2. GoogleMap的鼠标点击标注、搜索和设置城市的简单应用

    资源 Google Map API包含了大量的文档.示例和各种资料.在使用前需要申请自己的密钥 墙内要用:http://maps.google.cn/maps/api/js? 墙外可用:https:/ ...

  3. Windows 10 优化

    ---恢复内容开始--- 0x00 使开始菜单,任务栏,和操作中心透明 --关闭 右下角开始菜单,选择设置,打开个性化菜单,找到颜色一栏.向下滑至最低端,使开始菜单,任务栏,和操作中心透明选项关闭 0 ...

  4. Android sdk 更新失败解决方发整理

    解决办法: 设置本地hosts windows里hosts位置在C:\Windows\System32\drivers\etc,找到hosts文件 直接在hosts文件的最后加一行: 74.125.2 ...

  5. django form 表单验证

  6. php 写入数据库时Call to a member function bind_param() on a non-object

    <?php $servername = "localhost"; $username = "username"; $password = "pa ...

  7. 爬虫入门【1】urllib.request库用法简介

    urlopen方法 打开指定的URL urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, ca ...

  8. HTML/CSS/JS初始化

    CSS <link type="text/css" href="http://www.mazey.cn/css/mazey-base.css" rel=& ...

  9. NOI-linux下VIM的个人常用配置

    路径:/etc/vim/vimrc 打开终端:Ctrl+Alt+T 输入:sudo vim或gedit /etc/vim/vimrc (推荐用gedit,更好操作) 以下是我的配置: "我的 ...

  10. 聊聊数据库~6.SQL运维中篇

    上篇回顾:https://www.cnblogs.com/dotnetcrazy/p/10810798.html#top 1.6.5.MySQL日志相关 本文的测试环境:MySQL5.7.26.Mar ...