算法讲解—最小生成树(Kruskal 算法)
算法讲解—最小生成树(Kruskal 算法)
简介
根据度娘的解释我们可以知道,最小生成树(Minimum Spanning Tree, MST)就是:一个有 n n n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n n n 个结点,并且有保持图连通的最少的边。
简单点来说就是求最小的连通图,就是从一个点能到达图的任意一点,且花费的代价最小(所有边的权值最小)。
最小生成树问题通常用于网络设计、电路设计等领域,目的是找到连接所有节点的最低成本方式。常见的算法有克鲁斯卡尔算法(Kruskal)和普里姆算法(Prim)等。

Kruskal 算法
要实现最小生成树,最著名的就是 Kruskal 算法。
Kruskal 算法是一种用来求解最小生成树问题的贪心算法。最小生成树问题是指在一个连通带权无向图中找到一个生成树,使得所有边的权重之和最小。
Kruskal 算法的基本思想是从小到大选择边,直到选出 n − 1 n-1 n−1 条边为止( n n n 为节点数)。具体步骤如下:
-
将图中的所有边按照权重从小到大进行排序。
-
初始化一个空的集合 M M M,用来存放最小生成树的边。
-
遍历排序后的边,如果当前边的两个端点不在同一个连通分量中,则将这条边加入集合 M M M ,并将两个端点所在的连通分量合并。
-
重复步骤 3 3 3,直到集合 M M M 中的边数达到 n − 1 n-1 n−1 条,其中 n n n 为节点数。
-
最后得到的集合 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 算法)
算法讲解—最小生成树(Kruskal 算法) 简介 根据度娘的解释我们可以知道,最小生成树(Minimum Spanning Tree, MST)就是:一个有 n n n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n n n 个结点…...
掌握 C# 多线程与异步编程
现代应用程序通常需要执行复杂的计算或处理 I/O 操作,这些操作可能会导致主线程阻塞,从而降低用户体验。C# 提供了多线程与异步编程的多种工具,让我们能够高效地并发处理任务。本文将介绍 C# 中的多线程与异步编程,包括 Thread 类…...
Angular 2 用户输入
Angular 2 用户输入 Angular 2 是一个由 Google 维护的开源前端 web 框架,用于构建单页应用程序(SPA)。它以其高效的双向数据绑定、模块化架构和强大的依赖注入系统而闻名。在 Angular 2 应用程序中,处理用户输入是核心功能之一,因为它允许应用程序响应用户的操作。 Ang…...
线程安全的单例模式 | 可重入 | 线程安全 |死锁(理论)
🌈个人主页: 南桥几晴秋 🌈C专栏: 南桥谈C 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据…...
解决方案:梯度提升树(Gradient Boosting Trees)跟GBDT(Gradient Boosting Decision Trees)有什么区别
文章目录 一、现象二、解决方案梯度提升树(GBT)GBDT相同点区别 一、现象 在工作中,在机器学习中,时而会听到梯度提升树(Gradient Boosting Trees)跟GBDT(Gradient Boosting Decision Trees&…...
亚马逊国际商品详情API返回值:电商精准营销的关键
亚马逊国际商品详情API(Amazon Product Advertising API)为开发者提供了一种获取商品信息的方式,这些信息对于电商精准营销至关重要。通过分析API返回的详细数据,商家可以制定更精准的营销策略,提高用户购买转化率。 …...
python爬虫 - 进阶requests模块
🌈个人主页:https://blog.csdn.net/2401_86688088?typeblog 🔥 系列专栏:https://blog.csdn.net/2401_86688088/category_12797772.html 目录 前言 一、SSL证书问题 (一)跳过 SSL 证书验证 ࿰…...
代码随想录 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.排序的概念 排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。 稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序…...
Springboot 整合 durid
文章目录 Springboot 整合 druiddruid的优势配置参数使用整合 Druid配置数据源配置参数绑定配置参数配置监控页面配置拦截器 Springboot 整合 druid druid的优势 可以很好的监控 DB 池连接 和 SQL 的执行情况可以给数据库密码加密可以很方便的编写JDBC插件 配置参数 使用 整…...
JVM 系列知识体系全面回顾
经过几个月的努力,JVM 知识体系终于梳理完成了。 很早之前也和小伙伴们分享过 JVM 相关的技术知识,再次感谢大家支持和反馈。 最后再次献上 JVM系列文章合集索引,感兴趣的小伙伴可以点击查看。 JVM系列(一) -什么是虚拟机JVM系列(二) -类的…...
crossover软件如何安装程序 及最新图文案张教程
IT之家 2 月 23 日消息,CodeWeavers 近日发布了 CrossOver 24 版本更新,基于近期发布的 Wine 9.0,不仅兼容更多应用和游戏,还初步支持运行 32 位应用程序。 苹果在 macOS Catalina 系统中移除对 32 位软件的支持之后,在…...
Python爬虫之正则表达式于xpath的使用教学及案例
正则表达式 常用的匹配模式 \d # 匹配任意一个数字 \D # 匹配任意一个非数字 \w # 匹配任意一个单词字符(数字、字母、下划线) \W # 匹配任意一个非单词字符 . # 匹配任意一个字符(除了换行符) [a-z] # 匹配任意一个小写字母 […...
Jenkins打包,发布,部署
一、概念 Jenkins是一个开源的持续集成工具,主要用于自动构建和测试软件项目,以及监控外部任务的运行。与版本管理工具(如SVN,GIT)和构建工具(如Maven,Ant,Gradle)结合使…...
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进行注入,构造post语句 unameaaa"passwdbbb&SubmitSubmit 页面报错,根据分析,闭合方式". 确定列数 构造 unameaaa" or 11 # &passwdbbb&SubmitSubmit 确定存在注…...
Python开发环境配置(mac M2)
1. 前言 作为一名程序员,工作中需要使用Python进行编程,甚至因为项目需要还得是不同版本的Python如何手动管理多个版本的Python,如何给Pycharm(IDE)配置对应的interpreter等,都成为一个 “不熟练工” 的难…...
其他: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 中隐藏元素刷新闪烁问题
一、问题说明 页面刷新,原本隐藏的元素会一闪而过。 效果展示: 页面的导航栏通过路由跳转中携带的 meta 参数控制导航栏的 显示/隐藏,但在实践过程中发现,虽然元素隐藏了,但是刷新页面会出现闪烁的问题。 项目源码&…...
【MySQL】数据目录迁移
一、使用场景 使用该方法一般是数据目录所在磁盘不支持扩展,只能通过新加磁盘来扩展数据目录磁盘空间。通常是Windows服务器,或者是Linux服务器的mysql数据目录的磁盘没有使用lvm。 二、准备工作 1. 新磁盘初始化,达到可使用状态 2. 需要自己…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
