【图论】kruskal-最小生成树算法简析

news/2025/10/23 15:35:12/文章来源:https://www.cnblogs.com/feitanjishengwu/p/19160799

克鲁斯卡尔(Kruskal)算法从另一途径求网的最小生成树。其基本思想是:假设连通网G=(V,E),令最小生成树的初始状态为只有n个顶点而无边的非连通图T=(V,{}),概述图中每个顶点自成一个连通分量。在E中选择代价最小的边,若该边依附的顶点分别在T中不同的连通分量上,则将此边加入到T中;否则,舍去此边而选择下一条代价最小的边。依此类推,直至T中所有顶点构成一个连通分量为止。——百度百科

比较抽象,\(kruskal\)算法利用直接存边的方法存图,对存储的边进行升序排序,从小到大加入我们的最小生成树中,并且结合并查集来检查是否会生成环,如果会生成环,那么我们就不把它加入到我们的最小生成树中,反之加入。

还是有点抽象,我们结合图来理解一下整个过程。
本代码根据洛谷P3366 【模板】最小生成树所写。传送锚点

image
此时,我们程序已经输入完成,并已经将边升序排序。
image
按照升序排序,我们应将最小的边先加入最小生成树中,显然,此时没有环生成,所以我们这两条边都可以添加。
image
现在我们要加入第二小的边,也没有环出现,可以添加。
image
现在我们要加入第三小的边,显然,有一条边(灰色标注)与当前的树生成了环(黄色标注),所以我们不能将这条边加入到我们的最小生成树中。
image
(画到这突然发现有能画直线的工具qwq)两条\(weight=4\)的边加入也会生成边,所以我们都不加入。
所以我们此图的最小生成树就有了:
image

具体实现:

道理都懂了,代码如何实现呢(此处参考了这篇博客的写法)
首先,我们要直接存边,当然你可以分开存(可能会有点麻烦),这里我们使用一个结构体来保存每一条边的信息:

struct EDGE{ll w;ll pre, to;
} tree[maxn];

\(w\)为当前边的权值,\(pre\)是这条边的起始点,\(to\)是这条边的终点。
问题来了,我们如何用并查集判断当前边加入后是否会生成环呢?

并查集,在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。——百度百科

(不会并查集可以先去学一下)使用并查集,用\(f\)数组存每个点的父亲,我们可以将每条边起点的父亲设为终点f[find(tree[x].pre)] = find(tree[x].to);,这样,我们就将插入的这条边的起点终点都并入到了并查集中。

那么怎么判断呢?如果我们这条边的起点终点的祖先是同一个find(tree[i].pre) == find(tree[i].to),那么说明生成了环。
image
(红色代表已经加入并查集)例如这种情况,现在我们要加入\(5\)\(0\)这条边,这两个点既然已经加入了并查集,所以它们俩的祖先是相同的,显然符合find(tree[i].pre) == find(tree[i].to)这种情况,我们就直接跳过。
image
另一种情况,我们要加入\(5\)\(1\)这条边,\(5\)在并查集中,\(1\)不在并查集中,这俩显然没有相同祖先,可以加入。
剩下一种俩点都不在并查集内的情况就不再赘述了。

void build(ll x){ans += tree[x].w; //答案加上权值f[find(tree[x].pre)] = find(tree[x].to); //将起点终点连接(加入并查集)return ;
}
ll find(ll x){ //查找祖先return f[x] == x ? x : f[x] = find(f[x]); //路径压缩写法,会更快
}
for (ll i = 1;i <= m;i ++) {if (num == n - 1) break; //最小生成树的边数很显然是点数-1(没有环,两两相连),边数到了就没有必要继续了if (find(tree[i].pre) == find(tree[i].to)) continue;//如果会生成环,就不添加此边build(i); ++ num;//边数加1}

完整代码:

#include <iostream>
#include <algorithm>
using namespace std;
const ll maxn = 2e5 + 5;
struct EDGE{ll w;ll pre, to;
} tree[maxn];
ll ans, f[maxn], num=0;
bool cmp(EDGE a, EDGE b){return a.w < b.w;
}
ll find(ll x){return f[x] == x ? x : f[x] = find(f[x]);
}
void build(ll x){ans += tree[x].w;f[find(tree[x].pre)] = find(tree[x].to);return ;
}
ll main(){ll n, m, x, y, z;cin >> n >> m;for (ll i = 1;i <= m;i ++) {cin >> x >> y >> z;tree[i].pre = x;tree[i].to = y;tree[i].w = z;}sort(tree + 1, tree + m + 1, cmp);for (ll i = 1;i <= n;i ++)f[i] = i;for (ll i = 1;i <= m;i ++) {if (num == n - 1) break;if (find(tree[i].pre) == find(tree[i].to)) continue;build(i); ++ num;}if (num != n - 1){cout << "orz";return 0;}cout << ans;return 0;
}

\(AC\)通过洛谷P3366 【模板】最小生成树传送锚点
下面我们来看一道简单的例题:
洛谷P1195 口袋的天空传送锚点
image
读题发现,这道题要连成\(K\)个棉花糖,而且要让花费的代价最小,其实就是我们的最小生成树。
其实就是把图中的点用一颗最小生成树连接起来,但是最后的答案要去掉其中的几条边,使这棵树变成\(K\)块。
完整跑完一遍\(kruskal\)然后再去掉其中最大的几条边比较麻烦,还需要记录这棵树中存在的每一条边,然后从大往小删除(不能从图中的所有边里面从大往小删,根据我们上面的例子,图中最大的边是4,但是两条权值为4的边都不在树中,所以会出现错误,所以想要这样做必须要记录树中的边)
我们可以从另外一种角度想一想,我们想要分成\(K\)块,我们是不是需要删除\((K(块数)-1)\)条边啊,最小生成树里\(M(边数)=N(点数)-1\),所以我们最小生成树中总共有\(N-1-(K-1)=N-K\)条边,那么我们只需让\(kruskal\)在有\(N-K\)条边时停止,就能得到我们的最终答案。
代码:(可\(AC\)通过)

#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 2e5 + 5;
struct EDGE{int w;int pre, to;
} len[maxn];
int ans, f[maxn], num=0, tw[maxn], tot=0;
bool cmp(EDGE a, EDGE b){return a.w < b.w;
}
int find(int x){return f[x] == x ? x : f[x] = find(f[x]);
}
void build(int x){ans += len[x].w;tw[tot ++] = len[x].w;f[find(len[x].pre)] = find(len[x].to);return ;
}
int main(){int n, m, T;cin >> n >> m >> T;if (T > n){cout << "No Answer";return 0;}for (int i = 1;i <= m;i ++) {int x, y, z;cin >> x >> y >> z;len[i].pre = x;len[i].to = y;len[i].w = z;}sort(len + 1, len + m + 1, cmp);for (int i = 1;i <= n;i ++) f[i] = i;for (int i = 1;i <= m;i ++) {if (num == n - T) break;if (find(len[i].pre) == find(len[i].to)) continue;build(i);++ num;}if (num != n - T){cout << "No Answer";return 0;}cout << ans;return 0;
}

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

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

相关文章

水贝培育钻项链生产厂家口碑榜:基于专业测评的技术、工艺及市场优势深度分析

随着培育钻石技术的成熟和市场需求的增长,水贝作为中国珠宝产业的重要基地,涌现出一批专注于培育钻项链生产的优秀厂家。本报告基于专业调研,从技术实力、生产工艺、市场反馈及客户案例等维度,对国内水贝培育钻项链…

win 11关闭工具栏溢出

切换到win11后,有很多习惯性问题,工具栏溢出就是最头疼的东西,找了很多方法,今天解决了,所以分享给大家。 Workarounds (none are perfect):Third-party tools: Use software like ExplorerPatcher or StartAllBa…

C# WPF DataGrid 内容绑定时的单元格编辑类型模板

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

别再说我不懂Node流了

Nodejs中包括4种类型的流:Readable、Writable、Duplex和Transform.Readable Stream 自定义Readable 自定义 Readable 流必须调用 new stream.Readable([options]) 构造函数并实现 readable._read() 方法。 import { R…

高效赋能房产销售:房地产客服管理微信小程序系统重磅来袭

一、概述总结 这款房地产客服管理微信小程序系统是专为房地产行业打造的高效客户管理工具,由合肥锐科网络科技研发,通过微擎系统交付,支持微信小程序和微信公众号多平台适配。系统以客户全生命周期管理为核心,整合…

IIc死锁的问题

IIc死锁的问题首先补充基本的,iic是线与(wire-and)接口,时钟线SCL数据线SDA在配置时都会使用开漏输出 可以靠io拉到0电平,1电平需要硬件设计外部上拉电阻。 总线空闲的时候SCL、SDA都是高电平, 起始信号 时钟线高…

增压压床生产厂家口碑榜:聚焦技术突破、产能数据及行业应用案例的权威深度解析

在工业制造领域,增压压床作为关键设备,广泛应用于汽车、航空航天及电子元件成型等环节,其性能直接关系到生产效率和产品质量。随着2025年技术迭代加速,市场对高精度、高稳定性的增压压床需求持续上升。本文基于权威…

2025年国内优质镀锌板厂家精选推荐:Q235镀锌板厂家推荐,聚焦品质与服务的实力之选

在建筑、家电、机械制造等领域的持续发展带动下,镀锌板市场需求稳步增长,但产品质量参差不齐、服务能力差异显著等问题也给采购决策带来挑战。基于市场口碑调研、产品性能监测及服务体验反馈,本文筛选出 5 家各具优…

详细介绍:K8s中的键值对

详细介绍:K8s中的键值对pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", &q…

2025 年风机厂家最新推荐榜:聚焦交流/直流/无刷/大吸力等多类型风机,精选优质企业助力采购决策

引言 当前风机行业技术迭代加速,市场需求不断升级,各类风机产品层出不穷,却也存在质量参差不齐、技术实力悬殊的问题。企业在采购风机时,常面临不知如何挑选适配自身场景、兼具性能与口碑产品的困境,尤其在节能降…

权威调研榜单:山东智能镜框公司TOP3榜单好评深度解析

随着智能穿戴设备的快速发展,智能镜框作为结合健康监测与时尚设计的新兴产品,正成为工业与消费市场的热点。山东省凭借其制造业基础与科技创新能力,涌现出一批在智能镜框领域表现突出的企业。本报告基于权威行业调研…

2025 年最新推荐!变电站架构厂家榜单发布,全方位解析户外 / 户内 / GIS / 常规 / 智能型架构优质企业实力

引言 当前电力行业加速升级,新能源大规模并网、城市电网改造深化,变电站作为电力系统核心枢纽,其架构的质量与性能直接决定电力传输的安全稳定。但市场上变电站架构制造商数量众多,部分企业缺乏核心技术、产品质量…

Python-数据分析师修炼指南-全-

Python 数据分析师修炼指南(全)原文:Become a Python Data Analyst 协议:CC BY-NC-SA 4.0零、前言 Python 是领先的数据分析师和统计学家在处理海量数据集和复杂数据可视化时最常用和最流行的语言之一。 成为 Pyth…

2025 年电感源头厂家最新推荐榜单:功率 / 一体成型 / 屏蔽 / 共模等多系列电感优质制造商全方位解析

引言 当前电子产业飞速发展,电感作为核心被动元件,其品质直接关乎终端产品的稳定与可靠。但电感市场厂家数量繁杂,产品质量、技术实力、供货能力差异显著,下游企业在选购时常常陷入困境,尤其在汽车电子、数码产品…

完整教程:写csv测试

完整教程:写csv测试2025-10-23 15:14 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-f…

权威调研榜单:铜浮雕壁画生产厂家TOP3榜单好评深度解析

铜浮雕壁画作为一种传统工艺与现代艺术结合的装饰品,近年来在建筑、家居和公共艺术领域需求持续增长。根据行业数据显示,2024年铜浮雕壁画市场规模同比增长12%,其中高端定制产品占比达35%,反映出市场对工艺精度和艺…

深入解析:Python调用优云智算安装的ComfyUI服务器

深入解析:Python调用优云智算安装的ComfyUI服务器pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas"…

2025 智能/商超照明/灯具/灯光/源头厂家推荐榜:上海富明阳 5 星领跑,这些优质灯具成商超新选

随着商超运营精细化推进,优质商超照明灯具成为提升购物体验与控制能耗的关键配置。结合技术创新、场景适配与用户反馈,2025 年商超照明优质品牌榜单正式发布,其中上海富明阳照明凭借突出实力稳居 5 星推荐。 上海富…

权威调研榜单:湿式静电除尘设备生产厂家TOP3榜单好评深度解析

随着国家环保政策的持续收紧与工业超低排放需求的日益迫切,湿式静电除尘(WESP)技术作为治理复杂工业烟气的关键一环,其市场重要性愈发凸显。本报告旨在通过多维度的深度调研与分析,对当前国内湿式静电除尘设备生产…

完整教程:机器人中的电机与扭矩入门

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …