贪心法之prim算法和Kruskal算法

最小生成树

性质:n个节点生成的最小生成树有n-1条边 & 最小生成树里多加一条边能生成含该边的一个环

构造方法:Prim算法 & Kruskal算法

一、Prim算法:逐个点连通的方式构造最小生成树(时间复杂度O(n*n),适合稠密图)

稀疏图&稠密图:有很少条边或弧(边的条数|E|远小于|V|²)的图称为稀疏图(sparse graph),反之边的条数|E|接近|V|²,称为稠密图(dense graph)。

设计思想:

贪心法之prim算法和Kruskal算法

Prim算法是从一个点开始,在给的无向图中寻找这个点所连接的权值最小的边,并在树中连接这条边,再寻找树中节点在无向图连接的权值最小的边,找到之后要判断这条边是否会构成一个环,最小生成树中是不能出现环的。

伪代码如下:

贪心法之prim算法和Kruskal算法

下图的例子:①从点1开始,权值最小的边是(1,3),权值为1,连接;②点1和点3在原始无向图中权值最小的边是(3,6),权值为4,连接;③从点1、点3和点6中权值最小的边是(6,4),权值为2连接;④在点1、3、6、4中权值最小的边是(4,1)和(3,2),权值都为5,但是(4,1)连接后会构成环,所以不能连接(4,1);⑤再找点1、3、6、4、2中权值最小的边,连接(2,5),完成最小生成树的构造。

贪心法之prim算法和Kruskal算法

prim算法正确性证明:

贪心法之prim算法和Kruskal算法

贪心法之prim算法和Kruskal算法

贪心法之prim算法和Kruskal算法

贪心法之prim算法和Kruskal算法

贪心法之prim算法和Kruskal算法

贪心法之prim算法和Kruskal算法

代码实现如下:

贪心法之prim算法和Kruskal算法贪心法之prim算法和Kruskal算法
#include
#include
using namespace std;

int n,m;
int map[101][101];

void prim() //最小生成树 prim算法
{
cout< 为多少?
int closest[101]; //closest[i]存放树中哪个点到i点的边的权值最小 => 是哪个?
bool s[101];
s[1] = true; //选择1为树顶
int i,j,k;
for(i=2;i {
lowcost[i] = map[1][i];
s[i] = false;
closest[i] = 1;
}
int min;
for(i=1;i {
min = 100000;
k = 1;
for(j=2;j {
if((lowcost[j] {
min = lowcost[j];
k = j;
}
}
cout< s[k] = true;
for(j=2;j {
if((map[k][j] {
lowcost[j] = map[k][j];
closest[j] = k;
}
}
}
}

int main()
{
cin>>n>>m;
int i,a,b,tem;
memset(map,0x3f,sizeof(map)); //memset要用0x3f
for(i=1;i {
cin>>a>>b;
cin>>tem;
map[a][b] = tem;
map[b][a] = tem;
}
prim();
return 0;
}

View Code

运行结果:

贪心法之prim算法和Kruskal算法

二、Kruskal算法:按权值递增的顺序选择合适的边构造最小生成树(时间复杂度O(eloge),适合稀疏图)

PS:有很少条边或弧(边的条数|E|远小于|V|²)的图称为稀疏图(sparse graph),反之边的条数|E|接近|V|²,称为稠密图(dense graph)。

设计思想如下:

贪心法之prim算法和Kruskal算法

伪代码如下:

贪心法之prim算法和Kruskal算法

先找出权值最小的边,将两个点连接,再找权值第二小的边,判断连接这两个点是否会形成环,如果不会就连接,如果会就不连接。

下图的例子:①权值最小边(1,3)连接;②剩下的权值最小边(4,6),判断不会形成环,连接;③剩下的权值最小边(2,5),判断不会形成环,连接;④剩下的权值最小边(3,6),判断不会形成环,连接;⑤剩下的权值最小边只有(3,2)不会形成环,连接。

贪心法之prim算法和Kruskal算法

Kruskal算法正确性证明:

贪心法之prim算法和Kruskal算法

先介绍下 短接操作

贪心法之prim算法和Kruskal算法

贪心法之prim算法和Kruskal算法

贪心法之prim算法和Kruskal算法

贪心法之prim算法和Kruskal算法

贪心法之prim算法和Kruskal算法

代码实现:

贪心法之prim算法和Kruskal算法贪心法之prim算法和Kruskal算法
#include
#include
using namespace std;

int pre[101];
int u[101],v[101],edge[101]; //u,v分别为两个点,edge为两个点之间的边
int m,n;
int find(int x)
{
int root = x;
while(pre[root]!=root)
root = pre[root];
//路径压缩
int i,j;
i = x;
while(pre[i]!=root)
{
j = i;
i = pre[i];
pre[j] = root;
}
return root;
}

void kruskal() //最小生成树,Kruskal算法
{
cout< total = n-1;
while(total>0)
{
min = 10000000;
for(i=1;i {
if(u[i] == -1||v[i] == -1)
continue;
if(edge[i] {
min = edge[i];
minnum = i;
}
}
fu = find(u[minnum]);
fv = find(v[minnum]);
if(fu!=fv) //不连通,就连接两个点
{
cout< pre[fu] = fv;
total--;
}
edge[minnum] = 100000000; //改变已经找到的最小值
u[minnum] = -1;
v[minnum] = -1;
}
}

int main()
{
cin>>n>>m;
int i,a,b,tem;
for(i=1;i pre[i] = i;
for(i=1;i {
cin>>a>>b;
cin>>tem;
u[i] = a;
v[i] = b;
edge[i] = tem;
}
kruskal();
return 0;
}

View Code

运行结果:

贪心法之prim算法和Kruskal算法

Kruskal算法所需的计算时间为O(eloge)

参考:北大《算法设计与分析》公开课

王晓东《算法设计与分析》第二版

Original: https://blog.51cto.com/u_14251143/5338822
Author: mb5c9304c35413c
Title: 贪心法之prim算法和Kruskal算法

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/517732/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • jvm优化必知系列——监控工具

    这是jvm优化系列第二篇: jvm优化——垃圾回收 通过上一篇的jvm垃圾回收知识,我们了解了jvm对内存分配以及垃圾回收是怎么来处理的。理论是指导实践的工具,有了理论指导,定位问…

    大数据 2023年5月28日
    097
  • Qt QTableView之QSqlTableModel数据库显示及插入删除操作

    QTableView的使用 初始化QTableView控件 //设置tableview行表头 文字居中 horizontalHeader()->setDefaultAlign…

    大数据 2023年11月11日
    097
  • Flink中Window详解之Window的聚合函数ProcessWindowFunction

    Flink中Window详解之Window的聚合函数ProcessWindowFunction 原创 wx62be9d88ce2942022-07-01 17:46:08博主文章分…

    大数据 2023年5月25日
    085
  • 全面的Docker快速入门教程

    Docker中的三个重要概念 Docker中的三个重要概念分别是:Image(镜像),Container(容器),Repository(仓储)。 Image(镜像)一个特殊的文件系…

    大数据 2023年5月29日
    088
  • 深度学习前沿技术摘要

    目前的深度学习主要分为以下几个领域: ; 图像领域(CV) representative task 图像分类 目标检测,目标跟踪,动作检测 实例分割 超分辨率(去马赛克) 去雾去雪…

    大数据 2023年5月28日
    0105
  • Sqlite 记事本

    Sqlite 记事本-支持标签搜索 内容搜索 主要功能: 引导页 用户 登录 注册 搜索 按照标签查询 按照关键字查询 标签 数据库 增 删 改 查 显示方式 瀑布流显示 *线性显…

    大数据 2023年11月11日
    043
  • hive最近的学习汇总-20221110

    下个项目可能要用hive比较多之前对分区、分桶搞不明白趁着最近又学习了一下 ps:之前说的prophet在年底前一定会放上来的 hive是基于Hadoop构建的一套 数据仓库分析系…

    大数据 2023年11月13日
    083
  • Spark使用scala语言连接hive数据库

    一、步骤 step1:使用idea创建maven管理工具创建项目 step2:在main下添加resources文件夹,并设置为Resources root step3:拷贝Had…

    大数据 2023年11月13日
    055
  • kafka原理篇

    消息队列分类 点对点 发布/订阅 kafka介绍 kafka架构说明 Topic与Partition的关系 partition复制机制 Consumer与Topic的关系 消息队列…

    大数据 2023年5月28日
    070
  • flink-sql大量使用案例

    1. 介绍 本章节主要说明各类型 flink sql的先后编写执行顺序,另外简单写一些实际可用的案例。推荐大家使用 StreamPark 进行 flink sql 任务的开发和上线…

    大数据 2023年11月13日
    061
  • sqlite数据库

    SQLite,是一款轻型的数据库,它的设计目标是嵌入式的,而且已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windo…

    大数据 2023年11月10日
    040
  • Kafka与ELK实现一个日志系统

    1.概述 客户端应用程序在运行过程中可能会产生错误,例如调用服务端接口超时、客户端处理业务逻辑发生异常、应用程序突然闪退等。这些异常信息都是会产生日志记录的,并通过上报到指定的日志…

    大数据 2023年5月28日
    065
  • EMQX 入门实战(1)–安装及简单使用

    EMQX 是基于 Erlang/OTP 平台开发的开源物联网 MQTT 消息服务器,本文主要介绍其安装及简单使用,文中使用到的软件版本:emqx 4.4.2、Centos 7. 1…

    大数据 2023年5月25日
    062
  • Linux基础命令(一)

    linux基础命令(一) linux基础命令(一) 1.目录管理 1.1 ls 1.2 cd 1.3 pwd 1.4 mkdir 1.5 tree 2.文件管理 2.1 touch…

    大数据 2023年5月27日
    062
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球