Kruskal算法求最小生成树

  • 一、算法学习前先要知道
    • 1.最小生成树概念
    • 2.数据结构:并查集
  • 二、Kruskal算法实现步骤
    • 1.把所有的边排序
    • 2.遍历所有的边
  • 三、Kruskal算法的代码实现

一、算法学习前先要知道

1.最小生成树概念

对于无向图G(V,E),连接所有点V以及边集是E的子集的树称为G的生成树。而边的权值和最小的树即为G的最小生成树

2.数据结构:并查集

博客链接:并查集介绍以及例题

二、Kruskal算法实现步骤

1.把所有的边排序

把所有的边按照边的长度从小到大排序。对此,我们可以把边的起点,终点,长度封装成结构体,然后重写cmp函数来利用sort函数排序。

2.遍历所有的边

在排序完成后,我们从小到大依次遍历每一条边。此时对于每一条边的两个点u,v会有以下两种情况。

  • 情况1:u和v如果没在连通块中的话,把u和v连通。
  • 情况2:u和v如果在一个连通块中的话,跳过这条边。

以上判断连通块与连通的操作由并查集来完成,而并查集的时间复杂度可以看作常数,所以kruskal算法的时间复杂度为O(m)。

三、Kruskal算法的代码实现

例题链接:Acwing kruskal求最小生成树

给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环,边权可能为负数。求最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。给定一张边带权的无向图 G=(V,E),其中 V 表示图中点的集合,E 表示图中边的集合,n=|V|,m=|E|。由 V 中的全部 n 个顶点和 E 中 n−1 条边构成的无向连通子图被称为 G 的一棵生成树,其中边的权值之和最小的生成树被称为无向图 G 的最小生成树。输入格式
第一行包含两个整数 n 和 m。接下来 m 行,每行包含三个整数 u,v,w,表示点 u 和点 v 之间存在一条权值为 w 的边。输出格式
共一行,若存在最小生成树,则输出一个整数,表示最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。数据范围
1≤n≤1e5,
1≤m≤2∗1e5,
图中涉及边的边权的绝对值均不超过 1000。输入样例:
4 5
1 2 1
1 3 2
1 4 3
2 3 2
3 4 4
输出样例:
6

最小生成树板子题,是必须要掌握的例题

//#pragma GCC optimize(2)
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<map>
#include<stack>
#include<set>
#include<bitset>
#include<ctime>
#include<cstring>
#include<list>
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef  pair<int, int> PII;
const int N = 1e6 + 7;struct edge  //定义边的结构体
{int f, t, w;  //起点,终点,长度
}e[N];bool cmp(edge a, edge b)  //重写排序函数
{return a.w < b.w;
}int p[N];  //并查集祖先数组
int n, m;
int ans = 0;  //答案
int cnt = 0;   //计数器,记录存进最小生成树的边的数量
int find(int x)   //并查集查找函数
{if (x != p[x]) p[x] = find(p[x]);else return x;
}void init()  //并查集初始化
{for (int i = 0; i <= n; i++)p[i] = i;
}void kruskal()  //算法实现函数
{init();for (int i = 0; i < m; i++)  //遍历每一条边{int x = e[i].f, y = e[i].t, z = e[i].w;if (find(x) != find(y))  //不连通就连通{p[find(x)] = find(y);ans += z;cnt++;}}}void solve()
{cin >> n >> m;for (int i = 0; i < m; i++)   //边的输入{int a, b, c;cin >> a >> b >> c;e[i].f = a, e[i].t = b, e[i].w = c;}sort(e, e + m, cmp);  //排序函数kruskal();if (cnt == n - 1)   //如果生成树中边小于n-1就说明原图没有最小生成树cout << ans << endl;elsecout << "impossible" << endl;
}int main()
{std::ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);solve();return 0;
}

作者:Avalon Demerzel,喜欢我的博客就点个赞吧,更多图论与数据结构知识点请见作者专栏《图论与数据结构》

【图论】Kruskal算法求最小生成树详解相关推荐

  1. 图论 —— Kruskal 算法求最小生成树

    概述 Kruskal 算法是一种常见并且好写的最小生成树算法,由 Kruskal 发明.该算法的基本思想是从小到大加入边.算法实现基于贪心算法. 对于一个拥有 n n n 个顶点 m m m 条边的图 ...

  2. CSP认证201412-4 最优灌溉[C++题解]:最小生成树裸题、Kruskal算法求最小生成树

    题目分析 来源:acwing 分析:这是一道最小生成树的裸题. 这里默写Kruskal求最小生成树的最小费用的模板. 最小生成树模板请参考笔者的另一篇博文: 最小生成树板子-AcWing 859. K ...

  3. C语言实现克鲁斯卡尔Kruskal算法求最小生成树(附完整源码)

    Kruskal算法求最小生成树 Edge结构体,Graph结构体 Kruskal算法求最小生成树完整源码(定义,实现,main函数测试) Edge结构体,Graph结构体 // a structure ...

  4. Kruskal算法 - C语言详解

    最小生成树 在含有n个顶点的连通图中选择n-1条边,构成一棵极小连通子图,并使该连通子图中n-1条边上权值之和达到最小,则称其为连通网的最小生成树.  例如,对于如上图G4所示的连通网可以有多棵权值总 ...

  5. Prim算法和Kruskal算法求最小生成树

    Prim算法 连通分量是指图的一个子图,子图中任意两个顶点之间都是可达的.最小生成树是连通图的一个连通分量,且所有边的权值和最小. 最小生成树中,一个顶点最多与两个顶点邻接:若连通图有n个顶点,则最小 ...

  6. 用kruskal算法求最小生成树各边的权值之和

    [问题描述] 已知含有n个顶点的带权连通无向图,采用邻接矩阵存储,邻接矩阵以三元组的形式给出, 只给出不包括主对角线元素在内的下三角形部分的元素,且不包括不相邻的顶点对.求该连通图的最小生成树中各边的 ...

  7. prim算法求最小生成树_克鲁斯卡尔算法(Kruskal算法)求最小生成树

    上一节介绍了求最小生成树之普里姆算法.该算法从顶点的角度为出发点,时间复杂度为O(n2),更适合与解决边的绸密度更高的连通网.本节所介绍的克鲁斯卡尔算法,从边的角度求网的最小生成树,时间复杂度为O(e ...

  8. 最小生成树板子-AcWing 859. Kruskal算法求最小生成树

    题目分析 来源:acwing 分析: Kruskal算法思路: 将所有边按权重从小到大排序.算法瓶颈在此O(m×logm)O(m\times logm)O(m×logm) 枚举每条边:a和b是两个点, ...

  9. AcWing 859. Kruskal算法求最小生成树(稀疏图)

    题面连接 https://www.acwing.com/problem/content/861/ 思路 没啥好说的,就是贪心+破圈法,然后不断将最短的边加入集合中,可以参考我这篇博客 https:// ...

  10. Kruskal算法求最小生成树

    思路 在原图中选择最小的边权,加其加入到生成树中,若此边在生成树中成环舍去. 代码实现 struct node { int a, b, w;bool operator<(node t){retu ...

最新文章

  1. 2021 年音视频技术与发展
  2. mysql索引教程_MySQL教程96-MySQL索引类型
  3. OpenC 仿射变换
  4. 基于生成对抗网络(GAN)的人脸变形(附链接) | CSDN博文精选
  5. 成功企业的核心思维逻辑
  6. 利用队列实现车厢编组
  7. DirectShow开发快速入门之慨述
  8. MATLAB求线性代数的参数范围,MATLAB科学计算04(线性代数问题求解一)
  9. win10更新后开不了机_win7在线更新window10系统
  10. CRF++中的unigram和bigram features指定是uni/bigrams的输出标签
  11. Netlink 0007 --- 创建实现分析
  12. python-读取dcm文件-2021.5.24
  13. 深信服虚拟服务器设置ip,深信服服务器虚拟化asv操作步骤.pdf
  14. 远程软件工程师的10个最佳实践
  15. 债务美元是怎样“炼成”的
  16. CSS--盒子模型(box)--使用/教程/实例
  17. 那些年踩过的坑-之《Android Q-高通平台UAC(USB Audio Class)调试记录》
  18. 视频去水印工具-在线短视频去水印工具
  19. Android Studio 命令行Gradle编译
  20. SVG代码如何转为SVG文件

热门文章

  1. Goland的下载与安装
  2. 极简静态 Web 服务器
  3. Servlet(Request.Response)+文件上传
  4. 分享一个多功能SVN备份脚本
  5. 心理平衡其实就这么简单
  6. u-boot环境的擦除,默认设置,批写入
  7. 获取到的数组在webview中成了字符串
  8. 10562:Undraw the Trees
  9. ORA-00904:quot;T1quot;.quot;AREA_IDquot; :标识符无效
  10. ki4so-发起一个史上最开源的sso项目