最小生成树-Prim与Kruskal算法

文章目录

  • 什么是最小生成树?
  • Prim算法求最小生成树
    • Python实现:
  • Kruskal算法求最小生成树
      • 并查集
    • Python实现:
  • Reference

什么是最小生成树?

在图论中,树是图的一种,无法构成闭合回路的节点-边连接组合称之为树;
加权无向图中,连通一棵总权值最小的树称为最小生成树。

对于最小生成树的经典解法主要是Prim和Kruskal算法:

Prim算法求最小生成树

  1. 从任意节点开始,初始化生成树为空;
  2. 每次选择一条从已加入生成树的节点到未加入节点之间的最小边
  3. 将新的节点加入生成树,并更新所有未加入节点与生成树之间的最小边
  4. 重复步骤2-3,直到所有节点都加入生成树。

Python实现:

class Node:def __init__(self,node,length):self.node = nodeself.length = lengthclass Edge:def __init__(self, x, y, length):self.x = xself.y = yself.length = lengthclass Prim:def __init__(self,n,m):self.n = nself.m = mself.v = [[] for i in range(n+1)]       # 邻接表self.e = []   # 存放与当前节点相连的边self.s = []   # 存放最小生成树里的所有边self.vis = [False for i in range(n+1)]  # 用于存放每个节点是否已加入生成树的标记def graphy(self):# 用邻接表构建图for i in range(self.m):x, y, length = list(map(int, input().split()))self.v[x].append(Node(y,length))self.v[y].append(Node(x,length))def insert(self, point):# 找到一个新节点for i in range(len(self.v[point])):# 将最小边的新节点加入生成树if not self.vis[self.v[point][i].node]:self.e.append(Edge(point,self.v[point][i].node,self.v[point][i].length))self.vis[point] = Trueself.e = sorted(self.e, key = lambda e:e.length)def run(self, start):# 求解录入的无向连通图的最小生成树self.insert(start)for _ in range(self.n-1):for i in range(len(self.e)):if not self.vis[self.e[i].y]:self.s.append(self.e[i])self.insert(self.e[i].y)break# 判断是否存在连通if len(self.s) != (self.n - 1):print("error!")else:count = 0for i in range(len(self.s)):count += self.s[i].lengthprint(count)def main():n, m = list(map(int, input().split()))prim = Prim(n, m)prim.graphy()prim.run(1)if __name__ == '__main__':main()

Kruskal算法求最小生成树

  1. 对所有边按权重进行排序;
  2. 初始化一个空的生成树,以及一个并查集(Union-Find)来跟踪节点的连接情况;
  3. 逐条检查排序后的边,尝试将边加入生成树:
    a. 如果当前边连接的两个节点不在同一个集合,则加入该边,并合并这两个节点所在的集合;
    b. 如果当前边连接的两个节点已经在同一个集合,则跳过此边,避免形成环;
  4. 重复步骤3,直到生成树中有 (N-1,N是节点数) 条边。

并查集

并查集(Union-Find
Set)是一种高效的数据结构,主要用于解决一些动态连通性问题。它可以快速地判断某两个元素是否属于同一个集合,同时支持合并两个集合的操作。

并查集最常见的应用场景是:判断加权无向图中的连通性问题,例如:

判断两个节点是否属于同一个连通分量。 动态合并两个连通分量。

在这里插入图片描述

Python实现:

class Edge:def __init__(self, x, y, length):self.x = xself.y = yself.length = lengthclass Kruskal:def __init__(self, n, m):self.n = nself.m = mself.e = []   # 保存所有边self.s = []   # 存放最小生成树里的所有边self.parent = list(range(n+1))for i in range(m):x,y,length = list(map(int,input().split()))self.e.append(Edge(x,y,length))self.e.sort(key = lambda e:e.length)def find(self,f):if f == self.parent[f]:return felse:self.parent[f] = self.find(self.parent[f])return self.parent[f]def merge(self,fa,fb):a = self.find(fa)b = self.find(fb)self.parent[a] = bdef run(self):for j in range(self.m):ed = self.e[j]if self.find(ed.x) != self.find(ed.y):self.s.append(ed)self.merge(ed.x, ed.y)if len(self.s) != self.n - 1:print("error!")else:count = 0for i in range(len(self.s)):count += self.s[i].lengthprint(count)def main():n,m = list(map(int,input().split()))kruskal = Kruskal(n,m)kruskal.run()if __name__ == "__main__":main()

Reference

最小生成树:Prim算法和Kruskal算法
蓝桥云课-最小生成树
并查集

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/60988.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入理解 Java 基本语法之数组

目录 一、数组基础概念 二、数组的声明 1. 基本数据类型数组声明: 2. 引用数据类型数组声明: 三、数组的创建 四、数组的初始化 五、数组的使用 ​编辑1. 获取长度以及访问元素: 2. 数组作为方法的参数: 3. 数组作为方法…

计算机毕业设计PySpark+Scrapy农产品推荐系统 农产品爬虫 农产品商城 农产品大数据 农产品数据分析可视化 PySpark Hadoop

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

17. C++模板(template)1(泛型编程,函数模板,类模板)

⭐本篇重点:泛型编程,函数模板,类模板 ⭐本篇代码:c学习/07.函数模板 橘子真甜/c-learning-of-yzc - 码云 - 开源中国 (gitee.com) 目录 一. 泛型编程 二. 函数模板 2.1 函数模板的格式 2.2 函数模板的简单使用 2.3 函数模板…

ICPM端口的用途是什么?

‌ICMP(Internet Control Message Protocol,互联网控制报文协议)‌是TCP/IP协议簇的一个子协议,主要用于在IP主机和路由器之间传递控制消息。这些控制消息包括网络通不通、主机是否可达、路由是否可用等信息,虽然不传输…

Jupyter Notebook的安装和配置提示功能

Python开发环境搭建conda管理环境-CSDN博客 安装anaconda和对接到编译器的教程可以看上面这一篇 Jupyter Notebook是一种交互式计算环境,它允许用户在单个文档中编写和执行代码、方程、可视化和文本。与其他编译器相比,Jupyter Notebook的突出点在于其交…

视图查询中投影裁剪规则的原理和解析 | OceanBase 查询优化

背景 在SQL查询中使用视图查询时,执行中可能会产生的较多的中间结果集。为了优化这类查询的执行,OceanBase 引入了投影裁剪规则。能够识别出父查询中未实际使用的列,并将这些列从视图查询的select列表中剔除,进而提升整体查询的性…

maxun爬虫工具docker搭建

思路来源开源无代码网络数据提取平台Maxun 先把代码克隆到本地(只有第一次需要) git clone https://github.com/getmaxun/maxun.git 转到maxun目录 cd maxun 启动容器 docker-compose --env-file .env up -d 成功启动六个容器 网址 http://local…

剑指Offer26.树的子结构

题目让判断B是不是A的子结构 但是我们进行判断是基于 两个树的根相等时, 去判断是否为子结构 针是否等于B的根节点的值对A做先序遍历的过程中 如果根节点相同我们去判断此时B是不是以该根节点的子树的子结构! 实际上进行先序遍历的同时要进行递归判断子结构 B是不是A节点的子结…

2024御网杯信息安全大赛个人赛wp(misc方向)

目录 一.信息安全大赛的通知二、编码转换1. 第一部分2. 第二部分3. 第三部分 三、1.txt四、buletooth 题目附件以及工具链接: 通过网盘分享的文件:御网杯附件 链接: https://pan.baidu.com/s/1LNA6Xz6eZodSV0Io9jGSZg 提取码: jay1 –来自百度网盘超级会…

【云计算网络安全】解析 Amazon 安全服务:构建纵深防御设计最佳实践

文章目录 一、前言二、什么是“纵深安全防御”?三、为什么有必要采用纵深安全防御策略?四、以亚马逊云科技为案例了解纵深安全防御策略设计4.1 原始设计缺少安全策略4.2 外界围栏构建安全边界4.3 访问层安全设计4.4 实例层安全设计4.5 数据层安全设计4.6…

JavaScript 判断字符串是否包含子字符串的几种方法

这里写目录标题 方法 1: 使用 includes()方法 2: 使用 indexOf()方法 3: 使用正则表达式方法 4: 使用 search()方法 5: 用 startsWith() 或 endsWith()推荐使用 JavaScript 判断字符串是否包含子字符串,不要只知道 indexOf() ,还可以尝试一下其他写法。 …

实战OpenCV之物体跟踪

基础入门 物体跟踪技术是一种计算机视觉领域的重要技术,用于连续地检测和定位视频序列中的一个或多个目标物体。物体跟踪技术在众多领域都有广泛的应用,比如:自动驾驶、安防监控、增强现实等。物体跟踪的基本流程包含以下几个主要步骤。 1、初…

Vue前端进阶面试题(六)

以下是对您提出问题的详细解答: Vue 性能优化的方法 组件划分与按需加载: 通过合理划分组件,减少单个组件的复杂度。使用 Vue Router 的路由懒加载和 import() 进行按需加载。 使用 v-once 和 v-if: 使用 v-once 对静态内容进行一…

c#异步编程(async/await)

注:下文摘自ChatGPT,总结与案例都非常完善,可以快速理解并应用 0:使用场景 在winform界面程序中,在ui操作中涉及到一些耗时的等待操作,使用线程自己处理已经显得力不从心,如何能更好的实现&am…

Linux环境变量(添加环境变量、修改系统环境变量、内建命令和非内建命令)

Linux环境变量(添加环境变量、修改系统环境变量、内建命令和非内建命令) 1. 环境变量的介绍 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。环境变量是在操作系统中一个具有特定名字…

Python 3 教程第2篇(基础语法)

编码 默认情况下,Python 3 源码文件以 UTF-8 编码,所有字符串都是 unicode 字符串。 当然你也可以为源码文件指定不同的 编码: # -*- coding: cp-1252 -*-上述定义允许在源文件中使用 Windows-1252 字符集中的字符编码,对应适合语…

排序算法之插入排序篇

插入排序 思路&#xff1a; 就是将没有排序的元素逐步地插入到已经排好序的元素后面&#xff0c;保持元素的有序 视频的实现过程如下&#xff1a; 插入排序全过程 代码实现过程如下&#xff1a; public static void Insertion(int[] arr) { for (int i 1; i < arr.length…

AVL、B树和B+树

AVL树定义 AVL树&#xff08;Adelson-Velsky 和 Landis 树&#xff09;是一种自平衡的二叉搜索树&#xff08;Binary Search Tree, BST&#xff09;&#xff0c;由苏联数学家Georgy Adelson-Velsky和Evgenii Landis在1962年提出。AVL树通过在每个节点上维护一个平衡因子&#…

Unity ShaderLab 实现3D物体描边

实现思路&#xff1a; 给物体添加第二个材质球&#xff0c;在shader的顶点着色器中使顶点的位置变大&#xff0c;然后在片元着色器中输出描边颜色。 shader Graph实现如下&#xff1a; ShaderLab实现如下&#xff1a; Shader "Custom/Outline" {Properties{[HDR]_…

【C++第三方库】Muduo库结合ProtoBuf库搭建服务端和客户端的过程和源码

每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” 绪论​&#xff1a; 本章我将结合之前的这俩个第三方库快速上手protobuf序列化和反序列化框架和muduo网络&#xff0c;来去实现muduo库在protocol协议搭建服务端和客户端。…