hiho刷题日记——第二十九天最小生成树三·堆优化的Prim算法

最小生成树之prim算法(优先队列优化) prim算法适合稠密图,即边数较多而点较少的情况,时间复杂度为n^2,堆优化的情况下,如果点数为m,边数为n,可以达到nlongm,我还是习惯用优先队列写这个算法,思想很简单,就是每次寻找一条由已加入集合的点和与它们相邻的没加入集合的点的权值最小边(有点绕理解下),进行n-1次就找出来了,也是贪心的思想,实现就是随便找一个初始节点,然后建一个最小堆(边小的先pop出来),把该节点的vis值置为1,遍历该节点相邻的节点,如果没有被vis标记过,就加入边到堆中,扫完了以后处理堆中数据,如果弹出的边被标记过就po 阅读详情

题目

最小生成树。

思路

使用小根堆对prim算法进行优化。
参考第二十六天和第二十八天。

代码

#include<cstdio>
#include<cstring>
using namespace std;

const int MAXN=100000+1;
const int MAXM=1000000+1;
int N,M,vis[MAXN];
int head[MAXN],e=0;
int w[MAXM],top=1;
struct EDGE
{
    int v,next,cost;
}edge[MAXM<<1];

void addEdge(int x,int y,int z)
{
  edge[e].v=y;
  edge[e].cost=z;
  edge[e].next=head[x];
  head[x]=e++;
}

void add(int p)
{
  int i=top++;
  while(i!=1 && edge[w[i>>1]].cost>edge[p].cost)
  {
    w[i]=w[i>>1];
    i>>=1;
  }
  w[i]=p;
}

int out()
{
  int ans=w[1];
  int i=1;

  w[1]=w[--top];
  while((i=i<<1)<top)
  {
    i=((i|1)>=top || edge[w[i]].cost<edge[w[i|1]].cost)?i:i|1;
    if(edge[w[i>>1]].cost>edge[w[i]].cost)
    {
      w[i>>1]=w[i];
      w[i]=w[top];
    }
    else break;
  }
  return ans;
}

int prim()
{
    int ans=0,k;
    memset(vis,0,sizeof(vis));
  vis[1]=1;
  for(int i=head[1];i!=-1;i=edge[i].next) add(i);
    for(int i=1;i<N;i++)
    {
        do{k=out();} while(vis[edge[k].v]);
        vis[edge[k].v]=1; ans+=edge[k].cost;
        for(int p=head[edge[k].v];p!=-1;p=edge[p].next) if(!vis[edge[p].v]) add(p);
    }
    return ans;
}

int main()
{
  memset(head,-1,sizeof(head));
    scanf("%d%d",&N,&M);
  int a,b,c;
  while(M--)
  {
    scanf("%d%d%d",&a,&b,&c);
    addEdge(a,b,c);
    addEdge(b,a,c);
  }

    printf("%d",prim());

    return 0;
}
prim算法堆优化 首先,prim算法的思想是,从一个起点开始,通过不断的纳入与当前生成树距离最短的且不在生成树中的点来构造最小生成树,当所有点都纳入到生成树以后,就得到了最小生成树。使用邻接表来存储图,能使得所需的空间最小。通过一个数组来存放各个点到当前生成树的最短距离,可以避免重复比较,从而提升效率。但我们所要获取的是该数组里的距离最小的那个点。如果没有进行堆优化,那从这个数组里找出最小距离的点的时间复杂度是O(n),通过堆优化,我们获取最小值的时间复杂度则为O(log2n),在图的点数目很大时,能有效的提升效率。 #in 阅读详情

相关推荐

手势控制 Python !Leap Motion Python 开发教程 (二)

手势控制 Python !Leap Motion Python 开发教程 (二) 现在进入正题,我来给大家总结一下我在使用 Leap Motion 开发过程中的经验以及学到的东西,其中我会概括以及翻译官方给出的注释,为了让这些注释更加通俗易懂,让大家更好理解。 回顾 在上一篇文章中我们讲了如何配置 Leap Motion 的 Python 2.7 的开发环境,如果您还没有配置好您的开发环境,可以参...

成畅的博客 3193

最小生成树prim算法——堆优化模板(邻接矩阵存储)

#include <bits/stdc++.h> using namespace std; const int inf = 0x3f3f3f3f; int n, m; int dis[105], vis[105]; struct node { int v, dis; node(int a, int b): v(a), dis(b) {}; bool operator <(co

yiqzq的博客 1166

用Python和CasADi实现高斯伪谱法:一个轨迹优化问题的保姆级教程

本文详细介绍了如何使用Python和CasADi框架实现高斯伪谱法解决轨迹优化问题。通过保姆级教程,从环境准备、问题建模到高斯伪谱法的核心实现,包括配点与权重计算、微分矩阵构造和动力学约束实现,最终完成问题求解与结果可视化。适用于机器人轨迹规划和无人机路径优化等工程场景。

weixin_30776273的博客 293

prim算法的堆优化。

/** 堆prime的优化,主要从for循环里的两个for循环下手: 第一个for循环是找最小值,方式使用堆进行优化; 对第二个for循环,用邻接表进行操作。 **/ for(int i = 1; i<n; i++) { int temp_j = 0; int min_c = 0x3f3f3f;

袁汉春 5250

PBR:双向反射分布函数(BRDF)介绍与Cook-Torrance模型的实现

PBR:双向反射分布函数(BRDF)介绍与Cook-Torrance模型的实现 BRDF简介 再介绍BRDF之前我们要引入渲染方程这个东西: 其中L表示辐射率,其公式为: 它表示了一个拥有辐射强度Φ的光源在单位面积A,单位立体角ω上的辐射出的总能量。 辐射率是辐射度量学上表示一个区域平面上光线总量的物理量,它受到入射光线与平面法线间的夹角θ的余弦值cosθ的影响:当直接...

小龙虾的博客 1万+

无人机飞控传感器全解析:从IMU到光流传感器的实战应用

本文深入解析了无人机飞控系统的核心传感器,从IMU、气压计、磁力计到光流传感器,详细阐述了其工作原理、数据融合策略及常见挑战。结合ICF5、Pixhawk 6C等主流飞控硬件,提供了从传感器校准、滤波器调优到应对室内光流定位、强磁干扰等实战场景的系统性优化指南,帮助开发者突破飞控“黑箱”,实现更稳定、可靠的飞行控制。

weixin_28396629的博客 167

Dijkstra算法的二叉堆优化

算法原理 每次扩展一个距离最小的点,再更新与其相邻的点的距离。 如何寻找距离最小的点 普通的Dijkstra算法的思路是直接For i: 1 to n 优化方案是建一个小根堆,小根堆里存储由当前结点更新距离的所有点,那么堆顶就是距离最小的点 如何寻找与源点相邻的点 当然是邻接表 具体实现 建一个小根堆heap[] ,用来存储结点的序号,用一个数组pos[i] 来存储第i个结点在堆中的位置,用一个标...

weixin_30872733的博客 725

FFmpeg魔改指南:让RTMP协议完美兼容H265的三种方法(含SRS适配技巧)

本文详细介绍了三种让RTMP协议兼容H265编码的FFmpeg魔改方案,包括基于官方补丁的标准改造、Intel的SVT-HEVC集成方案以及金山云的自定义扩展方案。文章重点解析了各方案的实现原理与适配技巧,并提供了在SRS 6.0服务器上进行深度配置和性能调优的完整实战指南,帮助开发者解决H265推流至传统RTMP服务器的兼容性问题。

weixin_29290947的博客 195

堆优化的prim算法

《挑战程序设计竞赛》中对最小生成树中的prim算法只给出了未优化形式,而对于堆优化,只是简单地分析了时间复杂度,而对于堆优化问题,网上的答案不多,因此手写一份堆优化代码模板(理解后可直接使用) //maxV是顶点最大数typedef pairP; struct Edge { int to, cost; }; vectoredge[maxV]; int V; int mincost[maxV

Xavier's blog 1884

高通SA8155P车载Camera开发避坑指南:从硬件拓扑到AIS服务调试全流程

本文详细解析了高通SA8155P车载Camera开发全流程,从硬件拓扑设计到AIS(Automotive Imaging System)服务调试,涵盖关键组件配置、软件架构剖析及高级调试技巧。通过实战经验分享,帮助开发者避开常见陷阱,优化系统性能,适用于智能驾驶系统的环境感知开发。

weixin_42550597的博客 331

绕过Cloudflare的两种简便方案

绕过Cloudflare的两种简便方案

自成背后的博客 1万+

Kruskal算法简明

Kruskal算法简明  Kruskal(克鲁斯卡)算法和Prim算法般用于解决最小生成树问题,网上还有一个Prim+Heap的算法,空间复杂度比较高,但是效率很高。  Kruskal理解起来感觉会比prim好理解一些,和prim一样需要结合贪心思想,只是Kruskal需要结合并查集来使用。  算法的大致思想就是,先把所有的点等地位的铺开,然后先找到两个距离最近的点,将它们连起来,然后再找两个距离最

LucienShui 896

Prim算法堆优化

#include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <math.h> #include <iostream> #include <string> #include <st...

weixin_30729609的博客 324

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

最短路径——Dijkstra算法以及二叉堆优化(含证明)

一般最短路径算法习惯性的分为两种:单源最短路径算法和全顶点之间最短路径。前者是计算出从一个点出发,到达所有其余可到达顶点的距离。后者是计算出图中所有点之间的路径距离。 单源最短路径 Dijkstra算法 思维 本质上是贪心的思想,声明一个数组dis来保存源点到各个顶点的最短距离和一个保存已经找到了最短路径的顶点的集合:S,原本的元素构成集合Q,初始时,原点 s 的路径权重被赋为 0 (dis[s...

weixin_34355715的博客 1186

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

prim算法+优化 模版

#include //大概要这些头文件 #include #include #include #include using namespace std; typedef pair pii; int head[30],next[200],point[200],val[200],size,dist[30]; //前向星及dist数组 bool vis[30]; void add (in

skysys的研究小屋 871

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

hiho刷题日记——第三十一天小Hi小Ho的惊天大作战:扫雷·二

题目这次的扫雷是二维的了。根据三种规则做一次判断,判断出一定是雷和一定不是雷的数量。 1.如果某一个被探明的格子里所标的数字为0,那么它相邻的8个格子里的未探明格子被认作是一定不是地雷的格子。 2.如果某一个被探明的格子里所标的数字为K,且它相邻的8个格子里正好有K个没有探明的格子的话,则这K个没有探明的格子被认作是一定是地雷的格子。 3.如果某两个探明了的格子A和B,他们中标明的数字分别为P

AngcFun的博客 1530

hiho刷题日记——第三十天小Hi小Ho的惊天大作战:扫雷·一

题目简化版扫雷,只有一行。 给出一行的周围3格中是雷的数量。 判断哪些一定是雷,一定不是雷。 思路因为给出的信息是环环相扣的,不用一个一个去试。 只需要试第一格是否为雷就可以通过数据算出后面是否为雷。 所以只用试两次, 第一次把一格设为雷,算出后面的情况;第二次把第一格设为不是雷,算出后面的情况。 若两次都算出来了,则将两次的情况对比,没有变化的部分就是答案。 若只有一次满足条件,则

AngcFun的博客 1234

hiho刷题日记——第十二天刷油漆

题目一共N个结点的树(1至N编号),油漆能够涂M个结点。 将包含1号结点的一部分连通的结点进行涂漆(这里的连通指的是这一些涂漆的结点可以互相到达并且不会经过没有涂漆的结点),然后将剩下的结点拆掉!那么究竟选择哪些结点进行涂漆呢?小Ho想了想给每个结点都评上了分——他希望最后留下来,也就是涂漆了的那些结点的评分之和可以尽可能的高!输入每个测试点(输入文件)有且仅有一组测试数据。 每组测试数据的第一

AngcFun的博客 1014

hiho刷题日记——第九天状态压缩·二

hiho刷题日记——第九天天状态压缩·二题目小Hi和小Ho领到了一个大小为N*M的长方形盘子,他们可以用这个盒子来装一些大小为2*1的蛋糕。但是根据要求,他们一定要将这个盘子装的满满的,一点缝隙也不能留下来,才能够将这些蛋糕带走。这么简单的问题自然难不倒小Hi和小Ho,于是他们很快的就拿着蛋糕离开了~但小Ho却不只满足于此,于是他提出了一个问题——他们有多少种方案来装满这个N*M的盘子呢?代码#in

AngcFun的博客 971

hiho刷题日记——第十六天RMQ-ST算法

这两天有事停了两天。这道题也是调了不少时间。好累呀。真想就直接贴代码。ST定义ST[Len][L]表示左边界为L,长度为2^Len的区间中的最小值。则有 ST[Len][L]=min(ST[Len-1][L],ST[Len-1][L+2^(Len-1)]; 然后就可以循环求出所有的ST。答案取小于这个区间长度的最大的2的非负整数次幂T,则答案为min(ST[Len][L],ST[Len][R+1

AngcFun的博客 888

hiho刷题日记——第十一天树中的最长路

题目给出一个无根树(其实就可以之间看作一个特殊的无向图) 求出该无根树的最长路 样例输入 8 1 2 1 3 1 4 4 5 3 6 6 7 7 8 样例输出 6思路对于任意一个节点,将其视为根节点,找到深度最深的节点记录下来。 再将找到的节点作为根节点找出深度最深的节点,两点之间的路便是这无根树的最长路。原因假设我们已知了最长路的两个端点。那么将这颗无根树上的任意一个节点

AngcFun的博客 868

hiho刷题日记——第六天01背包

简单的01背包问题,简单的说就是将已有的资源发挥出最大的价值。

AngcFun的博客 743

hiho刷题日记——第十三天最近公共祖先·一

题目已知一棵族谱树。查找两个人的最近公共祖先。输入每个测试点(输入文件)有且仅有一组测试数据。 每组测试数据的第1行为一个整数N,意义如前文所述。 每组测试数据的第2~N+1行,每行分别描述一对父子关系,其中第i+1行为两个由大小写字母组成的字符串Father_i, Son_i,分别表示父亲的名字和儿子的名字。 每组测试数据的第N+2行为一个整数M,表示小Hi总共询问的次数。 每组测试数据的

AngcFun的博客 722

hiho刷题日记——第三天KMP算法

用KMP来求模式串在原串中的出现次数.

AngcFun的博客 702

hiho刷题日记——第八天状态压缩·一

当状态转移方程中状态过多时,进行压缩

AngcFun的博客 701
上一篇: hiho刷题日记——第二十八天题外话·堆
下一篇: hiho刷题日记——第三十天小Hi小Ho的惊天大作战:扫雷·一
昂村饭
博客等级 码龄12年 5粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值