当前位置: 首页 > news >正文

算法讲解—最小生成树(Kruskal 算法)

算法讲解—最小生成树(Kruskal 算法)

简介

根据度娘的解释我们可以知道,最小生成树(Minimum Spanning Tree, MST)就是:一个有 n n n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n n n 个结点,并且有保持图连通的最少的边。

简单点来说就是求最小的连通图,就是从一个点能到达图的任意一点,且花费的代价最小(所有边的权值最小)。

最小生成树问题通常用于网络设计、电路设计等领域,目的是找到连接所有节点的最低成本方式。常见的算法有克鲁斯卡尔算法(Kruskal)和普里姆算法(Prim)等。

Kruskal 算法

要实现最小生成树,最著名的就是 Kruskal 算法。

Kruskal 算法是一种用来求解最小生成树问题的贪心算法。最小生成树问题是指在一个连通带权无向图中找到一个生成树,使得所有边的权重之和最小。

Kruskal 算法的基本思想是从小到大选择边,直到选出 n − 1 n-1 n1 条边为止( n n n 为节点数)。具体步骤如下:

  1. 将图中的所有边按照权重从小到大进行排序。

  2. 初始化一个空的集合 M M M,用来存放最小生成树的边。

  3. 遍历排序后的边,如果当前边的两个端点不在同一个连通分量中,则将这条边加入集合 M M M ,并将两个端点所在的连通分量合并。

  4. 重复步骤 3 3 3,直到集合 M M M 中的边数达到 n − 1 n-1 n1 条,其中 n n n 为节点数。

  5. 最后得到的集合 M M M 就是最小生成树。

Kruskal 算法的时间复杂度主要取决于排序边的时间复杂度,通常使用快速排序等快速的排序算法,因此总的时间复杂度为 O ( E log ⁡ E ) O(E \log E) O(ElogE),其中 E E E 为边数。

需要注意的是,在实际应用中,Kruskal 算法还需要对图进行一些预处理,如可以先对边进行去重、排序等操作,以提高算法的效率。

引用一张百度的图片

代码实现

Python(由 AI 生成)

class DisjointSet:def __init__(self):self.parent = {}self.rank = {}def make_set(self, node):self.parent[node] = nodeself.rank[node] = 0def find_set(self, node):if self.parent[node] != node:self.parent[node] = self.find_set(self.parent[node])return self.parent[node]def union_sets(self, node1, node2):root1 = self.find_set(node1)root2 = self.find_set(node2)if root1 != root2:if self.rank[root1] > self.rank[root2]:self.parent[root2] = root1elif self.rank[root1] < self.rank[root2]:self.parent[root1] = root2else:self.parent[root2] = root1self.rank[root1] += 1def kruskal(edges, n):disjoint_set = DisjointSet()for i in range(n):disjoint_set.make_set(i)edges.sort(key=lambda edge: edge[2])result = []for edge in edges:node1, node2, weight = edgeroot1 = disjoint_set.find_set(node1)root2 = disjoint_set.find_set(node2)if root1 != root2:disjoint_set.union_sets(node1, node2)result.append(edge)return result

C++ (由 AI 生成)

#include <iostream>
#include <vector>
#include <algorithm>using namespace std;struct Edge {int u, v, weight;bool operator<(const Edge& other) const {return weight < other.weight;}
};int findParent(vector<int>& parent, int i) {if (parent[i] == -1) return i;return parent[i] = findParent(parent, parent[i]);
}void kruskal(vector<Edge>& edges, int n) {vector<int> parent(n, -1);int num_edges = 0;int result = 0;sort(edges.begin(), edges.end());for (const auto& edge : edges) {int u_parent = findParent(parent, edge.u);int v_parent = findParent(parent, edge.v);if (u_parent != v_parent) {parent[u_parent] = v_parent;result += edge.weight;num_edges++;if (num_edges == n - 1) break;  // 加上n-1条边即可构成最小生成树}}if (num_edges < n - 1) {cout << "无法构成最小生成树" << endl;} else {cout << "最小生成树的权值总和为: " << result << endl;}
}int main() {int n, m; // n为顶点数,m为边数cin >> n >> m;vector<Edge> edges(m);for (int i = 0; i < m; ++i) {int u, v, weight;cin >> u >> v >> weight;edges[i] = {u, v, weight};}kruskal(edges, n);return 0;
}

洛谷模版题

【洛谷】P3366 【模板】最小生成树

板子代码

#include <bits/stdc++.h>
using namespace std;
int n, m, sum, ans, fa[10005];
struct node {int x, y, z;
}f[200005];
int find(int x) {return x == fa[x] ? x : fa[x] = find(fa[x]);}
bool cmp (node a, node b) {return a.z < b.z;}
int main() {cin >> n >> m;for (int i = 1; i <= n; i ++) {fa[i] = i;}for (int i = 1; i <= m; i ++) {cin >> f[i].x >> f[i].y >> f[i].z;}sort (f + 1, f + m + 1, cmp);	for (int i = 1; i <= m; i ++) {if (find(f[i].x) != find(f[i].y)) {sum ++;fa[find(f[i].y)] = find(f[i].x);ans += f[i].z;	} else continue;if (sum == n - 1) {cout << ans;return 0;}}cout << "orz";return 0;
}

推荐好题

【洛谷】 P1194 买礼物
详细讲解

【洛谷】P1396 营救
详细讲解

【洛谷】P2820 局域网
详细讲解

【洛谷】P2330 SCOI2005 繁忙的都市
详细讲解

【洛谷】P3623 APIO2008 免费道路
详细讲解

参考

  • https://baike.baidu.com/item/%E6%9C%80%E5%B0%8F%E7%94%9F%E6%88%90%E6%A0%91/5223845?fr=ge_ala

  • https://blog.csdn.net/2301_79188764/article/details/142172901

  • https://www.dotcpp.com/course/1061

  • https://baike.baidu.com/item/%E5%85%8B%E9%B2%81%E6%96%AF%E5%8D%A1%E5%B0%94%E7%AE%97%E6%B3%95/4455899?fr=ge_ala

相关文章:

算法讲解—最小生成树(Kruskal 算法)

算法讲解—最小生成树&#xff08;Kruskal 算法&#xff09; 简介 根据度娘的解释我们可以知道&#xff0c;最小生成树(Minimum Spanning Tree, MST)就是&#xff1a;一个有 n n n 个结点的连通图的生成树是原图的极小连通子图&#xff0c;且包含原图中的所有 n n n 个结点…...

掌握 C# 多线程与异步编程

现代应用程序通常需要执行复杂的计算或处理 I/O 操作&#xff0c;这些操作可能会导致主线程阻塞&#xff0c;从而降低用户体验。C# 提供了多线程与异步编程的多种工具&#xff0c;让我们能够高效地并发处理任务。本文将介绍 C# 中的多线程与异步编程&#xff0c;包括 Thread 类…...

Angular 2 用户输入

Angular 2 用户输入 Angular 2 是一个由 Google 维护的开源前端 web 框架,用于构建单页应用程序(SPA)。它以其高效的双向数据绑定、模块化架构和强大的依赖注入系统而闻名。在 Angular 2 应用程序中,处理用户输入是核心功能之一,因为它允许应用程序响应用户的操作。 Ang…...

线程安全的单例模式 | 可重入 | 线程安全 |死锁(理论)

&#x1f308;个人主页&#xff1a; 南桥几晴秋 &#x1f308;C专栏&#xff1a; 南桥谈C &#x1f308;C语言专栏&#xff1a; C语言学习系列 &#x1f308;Linux学习专栏&#xff1a; 南桥谈Linux &#x1f308;数据结构学习专栏&#xff1a; 数据结构杂谈 &#x1f308;数据…...

解决方案:梯度提升树(Gradient Boosting Trees)跟GBDT(Gradient Boosting Decision Trees)有什么区别

文章目录 一、现象二、解决方案梯度提升树&#xff08;GBT&#xff09;GBDT相同点区别 一、现象 在工作中&#xff0c;在机器学习中&#xff0c;时而会听到梯度提升树&#xff08;Gradient Boosting Trees&#xff09;跟GBDT&#xff08;Gradient Boosting Decision Trees&…...

亚马逊国际商品详情API返回值:电商精准营销的关键

亚马逊国际商品详情API&#xff08;Amazon Product Advertising API&#xff09;为开发者提供了一种获取商品信息的方式&#xff0c;这些信息对于电商精准营销至关重要。通过分析API返回的详细数据&#xff0c;商家可以制定更精准的营销策略&#xff0c;提高用户购买转化率。 …...

python爬虫 - 进阶requests模块

&#x1f308;个人主页&#xff1a;https://blog.csdn.net/2401_86688088?typeblog &#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/2401_86688088/category_12797772.html 目录 前言 一、SSL证书问题 &#xff08;一&#xff09;跳过 SSL 证书验证 &#xff0…...

代码随想录 103. 水流问题

103. 水流问题 #include<bits/stdc.h> using namespace std;void dfs(vector<vector<int>>& mp, vector<vector<int>>& visit, int y, int x){if (visit[y][x] 1) return;visit[y][x] 1;if (y > 0){if (mp[y][x] < mp[y - 1][x…...

数据结构-排序1

1.排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&#xff0c;若经过排序…...

Springboot 整合 durid

文章目录 Springboot 整合 druiddruid的优势配置参数使用整合 Druid配置数据源配置参数绑定配置参数配置监控页面配置拦截器 Springboot 整合 druid druid的优势 可以很好的监控 DB 池连接 和 SQL 的执行情况可以给数据库密码加密可以很方便的编写JDBC插件 配置参数 使用 整…...

JVM 系列知识体系全面回顾

经过几个月的努力&#xff0c;JVM 知识体系终于梳理完成了。 很早之前也和小伙伴们分享过 JVM 相关的技术知识&#xff0c;再次感谢大家支持和反馈。 最后再次献上 JVM系列文章合集索引&#xff0c;感兴趣的小伙伴可以点击查看。 JVM系列(一) -什么是虚拟机JVM系列(二) -类的…...

crossover软件如何安装程序 及最新图文案张教程

IT之家 2 月 23 日消息&#xff0c;CodeWeavers 近日发布了 CrossOver 24 版本更新&#xff0c;基于近期发布的 Wine 9.0&#xff0c;不仅兼容更多应用和游戏&#xff0c;还初步支持运行 32 位应用程序。 苹果在 macOS Catalina 系统中移除对 32 位软件的支持之后&#xff0c;在…...

Python爬虫之正则表达式于xpath的使用教学及案例

正则表达式 常用的匹配模式 \d # 匹配任意一个数字 \D # 匹配任意一个非数字 \w # 匹配任意一个单词字符&#xff08;数字、字母、下划线&#xff09; \W # 匹配任意一个非单词字符 . # 匹配任意一个字符&#xff08;除了换行符&#xff09; [a-z] # 匹配任意一个小写字母 […...

Jenkins打包,发布,部署

一、概念 Jenkins是一个开源的持续集成工具&#xff0c;主要用于自动构建和测试软件项目&#xff0c;以及监控外部任务的运行。与版本管理工具&#xff08;如SVN&#xff0c;GIT&#xff09;和构建工具&#xff08;如Maven&#xff0c;Ant&#xff0c;Gradle&#xff09;结合使…...

CSS 实现楼梯与小球动画

CSS 实现楼梯与小球动画 效果展示 CSS 知识点 CSS动画使用transform属性使用 页面整体布局 <div class"window"><div class"stair"><span style"--i: 1"></span><span style"--i: 2"></span>…...

sqli-labs less-14post报错注入updatexml

post提交报错注入 闭合方式及注入点 利用hackbar进行注入&#xff0c;构造post语句 unameaaa"passwdbbb&SubmitSubmit 页面报错&#xff0c;根据分析&#xff0c;闭合方式". 确定列数 构造 unameaaa" or 11 # &passwdbbb&SubmitSubmit 确定存在注…...

Python开发环境配置(mac M2)

1. 前言 作为一名程序员&#xff0c;工作中需要使用Python进行编程&#xff0c;甚至因为项目需要还得是不同版本的Python如何手动管理多个版本的Python&#xff0c;如何给Pycharm&#xff08;IDE&#xff09;配置对应的interpreter等&#xff0c;都成为一个 “不熟练工” 的难…...

其他:Python语言绘图合集

文章目录 介绍注意导入数据函数模块画图 介绍 python语言的科研绘图合集 注意 This dataset includes the following (All files are preceded by "Marle_et_al_Nature_AirborneFraction_"):- "Datasheet.xlsx": Excel dataset containing all annual a…...

处理 Vue3 中隐藏元素刷新闪烁问题

一、问题说明 页面刷新&#xff0c;原本隐藏的元素会一闪而过。 效果展示&#xff1a; 页面的导航栏通过路由跳转中携带的 meta 参数控制导航栏的 显示/隐藏&#xff0c;但在实践过程中发现&#xff0c;虽然元素隐藏了&#xff0c;但是刷新页面会出现闪烁的问题。 项目源码&…...

【MySQL】数据目录迁移

一、使用场景 使用该方法一般是数据目录所在磁盘不支持扩展&#xff0c;只能通过新加磁盘来扩展数据目录磁盘空间。通常是Windows服务器&#xff0c;或者是Linux服务器的mysql数据目录的磁盘没有使用lvm。 二、准备工作 1. 新磁盘初始化&#xff0c;达到可使用状态 2. 需要自己…...

告别黑盒:用Python拆解OpenBCI GUI的滤波与可视化模块(附完整代码)

从零构建Python版OpenBCI数据处理引擎&#xff1a;解码脑电信号处理全流程 在脑机接口开发领域&#xff0c;OpenBCI以其开源特性和专业级性能成为众多研究者的首选硬件平台。然而&#xff0c;其官方GUI虽然功能完善&#xff0c;却像一座封闭的城堡——我们能看到华丽的城墙&…...

SAP-MM 公司间STO实战:从主数据到收货的完整配置与流程解析

1. 公司间STO的核心概念与业务场景 第一次接触公司间库存转储订单(STO)时&#xff0c;我误以为它和普通采购订单差不多。直到实际配置时才发现&#xff0c;这里面的门道可不少。简单来说&#xff0c;公司间STO就是集团内部不同法人公司之间的库存调拨业务&#xff0c;但会计上需…...

程序员鼓励师的消亡:当ChatGPT学会调情时

凌晨三点的代码战场凌晨三点的办公室&#xff0c;最后一行代码刚刚通过测试。疲惫的测试工程师瘫在椅上&#xff0c;屏幕右下角突然弹出消息&#xff1a;“亲爱的debug战士&#xff0c;今天的你又一次战胜了bug宇宙呢~&#xff08;眨眼emoji&#xff09;”。这不是人类同事的关…...

OpenClaw自动化视频处理:Qwen2.5-VL-7B分析关键帧生成视频摘要

OpenClaw自动化视频处理&#xff1a;Qwen2.5-VL-7B分析关键帧生成视频摘要 1. 为什么需要自动化视频摘要 作为一个经常需要处理大量视频素材的自媒体创作者&#xff0c;我长期被一个痛点困扰&#xff1a;如何快速了解长视频的核心内容。传统方法要么是手动拖动进度条随机查看…...

InstantID社区翻译计划:多语言支持的实现与贡献方式

InstantID社区翻译计划&#xff1a;多语言支持的实现与贡献方式 【免费下载链接】InstantID 项目地址: https://ai.gitcode.com/hf_mirrors/InstantX/InstantID InstantID作为一款创新的AI人脸编辑工具&#xff0c;正通过社区翻译计划打破语言壁垒&#xff0c;让全球用…...

WZ文件编辑神器:Harepacker-resurrected从入门到精通的完整指南

WZ文件编辑神器&#xff1a;Harepacker-resurrected从入门到精通的完整指南 【免费下载链接】Harepacker-resurrected All in one .wz file/map editor for MapleStory game files 项目地址: https://gitcode.com/gh_mirrors/ha/Harepacker-resurrected Harepacker-resu…...

OpenClaw技能市场:10个适配Qwen2.5-VL-7B的实用自动化模块

OpenClaw技能市场&#xff1a;10个适配Qwen2.5-VL-7B的实用自动化模块 1. 为什么需要为Qwen2.5-VL-7B定制技能&#xff1f; 当我第一次在本地部署Qwen2.5-VL-7B这个多模态模型时&#xff0c;最让我惊喜的是它对图像和文本的联合理解能力。但很快我发现一个问题&#xff1a;模…...

附链小程序测评:支持Word/PDF/PPT/EXCEL/压缩包上传,解决公众号文件嵌入难题

公众号运营中&#xff0c;文件分发存在明确痛点&#xff1a;推文无法直接嵌入附件&#xff0c;第三方链接常出现跳转繁琐、广告弹窗、文件过期等问题&#xff0c;增加运营成本且影响用户体验。附链小程序为微信生态原生工具&#xff0c;核心解决上述痛点&#xff0c;支持公众号…...

STM32移植LVGL图形库实战指南

1. LVGL图形库概述与STM32移植价值LittlevGL&#xff08;简称LVGL&#xff09;作为当前最受欢迎的嵌入式开源图形库之一&#xff0c;其设计哲学完美契合了资源受限的嵌入式环境。我在多个STM32项目中采用LVGL后发现&#xff0c;相比传统GUI方案&#xff0c;它具有三个显著优势&…...

从‘迷失’到‘秒达’:我用PyCharm的‘符号搜索’和‘调用链查看’重构了老项目

从‘迷失’到‘秒达’&#xff1a;我用PyCharm的‘符号搜索’和‘调用链查看’重构了老项目 接手一个缺乏文档的遗留代码库&#xff0c;就像被扔进一座没有地图的迷宫。上周我面对的就是这样一个Python项目——3万行代码&#xff0c;零文档&#xff0c;函数命名随意得像临时起意…...