Kruskal算法(最小生成树)

article/2025/9/16 9:50:47

上篇Prim算法简要的讲解了最小生成树。也提到过Prim算法堆优化,但本蒟蒻并没有贴Prim         (堆优化的代码)。至于为什么没有贴呢?上篇Prim算法blog末尾有说明。

好勒!咱们接着讲Kruskal算法。这跟Prim算法有很大的不同


Prim和Kruskal算法差异:

1:Prim复杂度为O(n^2+m)   而Kruskal的复杂度为O(mlogm)    //注:n:点数    m:边数

2:Prim算法思想是枚举点的联通情况进行延伸计算,因此枚举每个点造成了n^2的复杂度,而Kruskal的算法思想是枚举边的情况,之大大减少了枚举的数量且减少了复杂度

Kruskal基本思想:

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

Kruskal方法构造最小生成树的过程图解:

 

按权值由小到大的顺序排列的编辑是:(各边由起点序号,终点序号,权值表示) 

1.(4,6,30)   2.(2,5,40)   3.(4,7,42)   4.(3,7,45)   5.(1,2,50)   6.(4,5,50)   7.(3,4,52)   8.(1,3,60)

9.(2,4,65)  10.(5, 6, 70)

克鲁斯卡尔算法思想设计克鲁斯卡尔算法函数主要包括两个部分:首先是带权图G中e条边的权值的排序;其次是判断新选取的边的两个顶点是否属于同一个连通分量。对带权图G中e条边的权值的排序方法可以有很多种,各自的时间复杂度均不相同,对e条边的权值排序算法时间复杂度较好的算法有快速排序法、堆排序法等,这些排序算法的时间复杂度均可以达到O(elge)。判断新选取的边的两个顶点是否属于同一个连通分量的问题是一个在最多有n个顶点的生成树中遍历寻找新选取的边的两个顶点是否存在的问题,此算法的时间复杂度最坏情况下为O(n)

观察Kruskal算法:

无向连通网的最小生成树首先是一棵生成树,即它应该是一个使网中所有顶点相连通而所需边的条数为最小的子网络,且其代价和在所有生成树中为最小。因此,可以从网的连通性角度来观察Kruskal算法。

初始时,最小生成树就是网中所有顶点的集合,它们之间没有任何一条边连接,即它们自成一个连通分量。而Kruskal算法的执行过程其实就是一个选取网中权值为最小的边的过程,即将两个小的连通分量连接为较大的连通分量,直至所有顶点都在一个连通分量中为止。每当选取网中的一条边时总会出现以下两种情况之一: 

①该边所依附的两个顶点分属于不同的连通分量。这时,该边可以作为最小生成树的一条边,因为两个不同的连通分量通过这条边的连接而相连通,成为了一个连通分量 。

②该边所依附的两个顶点属于同一个连通分量。如果选取这条边作为最小生成树的一条边,则必将构成环。因为连通分量中任意两个顶点间都有路径相通,一旦再加入一条边,该边所依附的两个顶点之间就有了两条路径,即构成了环。故属于这种情况的边即使其权值小也应该舍弃

再结合例题+代码的方式进行讲解:

小二,上题!

例题:链接:http://oj.daimayuan.top/course/14/problem/691

代码实现:

//Kruskal算法:O(mlogm): m为边的数量
#include<bits/stdc++.h>//万能头文件
using namespace std;
const int M=100002;//边的数量
const int N=50001;//点的数量
struct Node//定义一个包含起点,终点,边权的结构体
{int x,y,v;bool operator<(const Node &A) const//重构//目的是进行边权由小到排序{return v<A.v;}
}a[M];int n,m,fa[N];
//并查集的基本操作,在数据结构专题里我有讲解,大佬们要是忘记了,可以去看看
int Find(int x)//找父节点
{if(x==fa[x]) return x;return fa[x]=Find(fa[x]);
}
//Kruskal算法
int Kruskal()
{for(int i=1;i<=n;i++) fa[i]=i;//初始化父节点sort(a+1,a+1+m);//将边权排序int ans=0,cnt=n;//ans记录最小生成树的值,cnt代表有多少个集合for(int i=1;i<=m;i++)//枚举边{int x=Find(a[i].x),y=Find(a[i].y);//找起点和终点所属的集合if(x!=y)//若是不在一个集合(父节点){fa[x]=y;//进行合并操作ans+=a[i].v;//加最小边权--cnt;//总集合树-1}if(cnt==1) break;//如果最终只有一个集合,说明已经生成了最小生成树,就结束循环}if(cnt!=1) return -1;//如果不为一个集合,返回-1else return ans;//否则返回最小生成树值
}int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=m;i++)//存图操作scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].v);printf("%d",Kruskal());
}

总结:

1.最小生成树的算法分为两种: Prim算法和Kruskal(本蒟蒻目前就只知道这两种)

2.Prim是在点上的操作,Kruskal是在边上的操作

3.Prim算法复杂度:O(n^2+m)               Prim(堆优化):O((m+n)logn) 

   Kruskal算法复杂度:O(mlogm)

来都来了,给个点赞和关注呗(路过的给本蒟蒻一个赞也行...QAQ)


http://chatgpt.dhexx.cn/article/jQ4faEiF.shtml

相关文章

最小生成树matlab求解

一、最小生成树 连通所有顶点且总路径最小修建连通7个城市的铁路网&#xff0c;可修建的路线和对应造价如图所示&#xff0c;如何修建使总费用最少&#xff1f; 问题分析&#xff1a; 连通7个城市&#xff1a;生成的图中&#xff0c;从任意顶点起步&#xff0c;沿着边一定可以…

最小生成树——贪心算法

文章目录 1.生成树和最小生成树1.1 问题的定义1.2 MST性质 2.普里姆算法&#xff08;Prim&#xff09;2.1 算法流程2.2 算法正确性证明2.3 算法实现2.4 时间复杂度2.5 测试代码 3.克鲁斯卡尔算法&#xff08;kruskal&#xff09;3.1 算法流程3.2 算法正确性证明3.3 算法实现 参…

C++ 最小生成树

目录&#xff1a; 前置知识 最小生成树 Prim 算法 kruskal 算法 前置知识&#xff1a; 连通图&#xff1a;在无向图中&#xff0c;若任意两个顶点 u 与 v 都有路径相通&#xff0c;则称该无向图为连通图。 强连通图&#xff1a;在有向图中&#xff0c;若任意两个顶点 u 与 …

最小生成树(C语言实现)

求这个网的最小生成树 /** 普里姆算法和克鲁斯卡尔算法求最小生成树* 采用邻接矩阵存储**/ #include<stdio.h>#define MAX_VERTEX_NUM 20 //图的定义 typedef struct {int vertexNum;int edgeNum;char vertex[MAX_VERTEX_NUM];int arc[MAX_VERTEX_NUM][MAX_VERTEX_NUM]…

最小生成树(C语言)

最小生成树问题&#xff08;C语言&#xff09; 所谓一个 带权图 的最小生成树&#xff0c;就是原图中边的权值最小的生成树 &#xff0c;所谓最小是指边的权值之和小于或者等于其它生成树的边的权值之和。 kruskal 克鲁斯卡尔算法&#xff08;Kruskal&#xff09;是一种使用贪…

最小生成树kruskal算法

最小生成树kruskal算法 概述算法分析代码 概述 克鲁斯卡尔 ( K r u s k a l ) (Kruskal) (Kruskal)算法是求连通网的最小生成树的另一种方法。与普里姆 ( P r i m ) (Prim) (Prim)算法不同&#xff0c;它的时间复杂度为 O ( e l o g e ) O(eloge) O(eloge)(e为网中的边数)&…

最小生成树:

定义&#xff1a; 将图中的 n 结点用 n-1 条边连接起来&#xff0c;使其各个边的权值之和最小的生成树。 普里姆算法&#xff1a; 从点的角度出发。 1、start 数组的值表示起始点的下标&#xff0c;start 的下标代表目的顶点&#xff1b;lowcost 数组的下标代表目的顶点&…

图——最小生成树

图——最小生成树 1. 基本概念 在一个连通无向图G(V, E)中&#xff0c;对于其中的每条边(u,v)∈E&#xff0c;赋予其权重w(u, v)&#xff0c;则最小生成树问题就是要在G中找到一个连通图G中所有顶点的无环子集T⊆E&#xff0c;使得这个子集中所有边的权重之和w(T) ∑ ( u , …

最小生成树的Kruskal算法-详解

最小生成树的Kruskal算法 一、 什么是最小生成树 1.1 最小生成树定义&#xff1a; 一个有 n 个结点的连通图的生成树是原图的极小连通子图&#xff0c;且包含原图中的所有 n 个结点&#xff0c;并且有保持图连通的最少的边。最小生成树可以用kruskal&#xff08;克鲁斯卡尔&a…

最小生成树(C语言简单实现)

最小生成树 本文参考自《大话数据结构》 一个连通图的生成树是一个极小的连通子图&#xff0c;它含有图中全部的顶点&#xff0c;但只有足以构成一棵树的n-1条边。我们把构造连通网的最小代价生成树称为最小生成树 。 找连通网的最小生成树&#xff0c;经典的有两种算法&#…

最小生成树怎么画?

介绍最小生成树的图形画法~以下图为例&#xff1a; 1、从1开始&#xff0c;以1为顶点画圈。在红色线经过的部分中&#xff0c;可见权重分别为6、1、5&#xff0c;最小权重为1。如下图。 2、以上图中得到的1、3为顶点的图中&#xff0c;继续画线&#xff0c;图为黄色线部分。经过…

最小生成树算法

最小生成树算法 生成树的概念最小生成树算法Prim算法Kruskal算法 生成树的概念 若图是连通的无向图或强连通的有向图&#xff0c;则从其中任一顶点出发&#xff0c;调用一次 d f s dfs dfs或者 b f s bfs bfs后&#xff0c;可以系统的访问图中所有顶点。若图是有根的有向图 &a…

【图】最小生成树

最小生成树&#xff1a;构造连通网的最小代价生成树。 最小生成树有两种算法&#xff1a;普利姆算法、克鲁斯卡尔算法。 普利姆&#xff08;Prim&#xff09;算法 加点&#xff0c;选择相邻点中边权最小的 需要两个一维数组&#xff0c;一个存权值&#xff0c;另一个存起始点…

最小生成树-Kruskal算法

数据结构:最小生成树-Kruskal算法 什么是最小生成树&#xff0c;最小生成树就是求图中把所有点都访问到的最短路径的长度 Kruskal算法采用的是边贪心思想&#xff0c;我们先大概讲一下它的大概思想&#xff0c;首先我们先假设先隐藏所有的边&#xff0c;这样每个点会成为一个连…

最小生成树(kruskal算法)

一、概述 最小生成树问题顾名思义&#xff0c;概括来说就是路修的最短。 接下来引入几个一看就明白的定义&#xff1a; 最小生成树相关概念&#xff1a; 带权图&#xff1a;边赋以权值的图称为网或带权图&#xff0c;带权图的生成树也是带权的&#xff0c;生成树T各边的权值…

最小生成树、最短路径树

一、最小生成树与最短路径树的区别 最小生成树能够保证整个拓扑图的所有路径之和最小&#xff0c;但不能保证任意两点之间是最短路径。 应用如网络部线&#xff0c;把所有的电脑(服务器&#xff1f;&#xff09;都连起来用的网线(光纤&#xff1f;&#xff09;最少&#xff0c…

【图解算法】最小生成树

今天我们介绍图论中的另一部分&#xff0c;最小生成树。 对图的最短路感兴趣的同学可以看&#xff1a; 【图解算法】一次解决最短路径问题 目录 1. 最小生成树简介2. Prim算法2.1 模板题2.2 思路模板2.3 代码实现2.3 prim 算法的优化 3. Kruskal算法3.1 模板题3.2 思路模板3.3…

数据结构—最小生成树

目录 一、生成树 二、最小生成树&#xff08;代价最小树&#xff09; 三、求最小生成树 1、Prim算法&#xff08;普里姆&#xff09; 2.Kruskal 算法&#xff08;克鲁斯卡尔&#xff09; 3.Prim算法和Kruskal算法对比 一、生成树 连通图的生成树是包含图中全部顶点的一个…

最小生成树详解

目录 最小生成树简介 什么是树 什么是生成树 什么是最小生成树 最小生成树的做法 Kruscal&#xff08;克鲁斯卡尔&#xff09;算法 思路 代码 其他算法 最小生成树简介 什么是树 树&#xff08;tree&#xff09;是一种特殊的图&#xff0c;一个图要成为树要满足三个条…

最小生成树的实现(C语言)

今天做洛谷的时候刷到好多图论的题&#xff0c;发现自己在这一方面算法的掌握还是有待提高啊。在这就先介绍最小生成树的算法吧。 最小生成树 最小生成树&#xff08;minimum spanning tree&#xff09;是由n个顶点&#xff0c;n-1条边&#xff0c;将一个连通图连接起来&…