最小生成树(kruskal算法)

一、概述

最小生成树问题顾名思义,概括来说就是路修的最短。

接下来引入几个一看就明白的定义:

最小生成树相关概念:

带权图:边赋以权值的图称为网或带权图,带权图的生成树也是带权的,生成树T各边的权值总和称为该树的权。

最小生成树(MST):权值最小的生成树。

最小生成树的性质:假设G=(V,E)是一个连通网,U是顶点V的一个非空子集。若(u,v)是一条具有最小权值的边,其中u∈U,v∈V-U,则必存在一棵包含边(u,v)的最小生成树。

完成构造网的最小生成树必须解决下面两个问题:

      (1)尽可能选取权值小的边,但不能构成回路;

      (2)选取n-1条恰当的边以连通n个顶点;

prim算法适合稠密图,kruskal算法适合简单图。

二、kruskal算法

kruskal远离更为简单粗暴,但是需要借助并查集这一知识。

(本人写的一篇https://blog.csdn.net/qq_41754350/article/details/81271567)

克鲁斯卡尔算法的基本思想是以边为主导地位,始终选择当前可用的最小边权的边(可以直接快排或者algorithm的sort)。每次选择边权最小的边链接两个端点是kruskal的规则,并实时判断两个点之间有没有间接联通。

现在我来模拟一下:

假如有以下几个城市,之间都有相连的道路:

最小生成树(kruskal算法)_第1张图片

根据kruskal的原理,我们需要对边权dis进行排序,每次找出最小的边。

排序后,最小的边自然是第8条边,于是4和6相连。

最小生成树(kruskal算法)_第2张图片

遍历继续,第二小的边是1号,1和2联通。

最小生成树(kruskal算法)_第3张图片

再后来是边3连接1,4。

最小生成树(kruskal算法)_第4张图片

dis也是14的还有边5,它连接3,4。

最小生成树(kruskal算法)_第5张图片

其次是dis为15的边4,但是2和4已经相连了,pass。

然后是dis为16的两条边(边2和边9),边2连接1和3,边9连接3和6,它们都已经间接相连,pass。

再然后就是dis为22的边10,它连接5和6,5还没有加入组织,所以使用这边。继续,发现此时已经连接了n-1条边,结束,最后图示如下:

最小生成树(kruskal算法)_第6张图片

 

原理如此简单,代码也很好实现(给个模板), 代码如下所示(注意细节):

#include
#include
#include
using namespace std;
int n,m,tot=0,k=0;//n端点总数,m边数,tot记录最终答案,k已经连接了多少边 
int fat[200010];//记录集体老大 
struct node
{
	int from,to,dis;//结构体储存边 
}edge[200010];
bool cmp(const node &a,const node &b)//sort排序(当然你也可以快排) 
{
	return a.dis

 

你可能感兴趣的:(最小生成树)