图论中最小生成树(Minimum Spanning Tree)

本文介绍了图论中的一个重要概念——最小生成树,以及两种经典算法:Prim算法和Kruskal算法。Prim算法通过逐步构建最小生成树,每次选择与已连接顶点集合边权最小的边;Kruskal算法则是不断选取未形成环的最小权值边。文章通过实例详细解析了两种算法的执行过程,并提及了连通分量的概念以及在判断环路时使用并查集的方法。
摘要由CSDN通过智能技术生成

转载自:最小生成树

一、图

图看成是一种由“顶点(node)”和“边(arc)”组成的抽象网络

对于通信问题:在各大城市中建设通信网络,如下图所示,每个圆圈代表一座城市,而边上的数字代表了建立通信连接的价格

Image

 问题:怎样才能以最小的价格使各大城市能直接或者间接地连接起来呢?

- 最小的价格

- 各大城市可以是直接或者间接相连的

可行解:

Image

 二、最小生成树

Image

对于一个图而言,它可以生成很多树,如右侧图2,图3就是由图1生成的。

- 从上面可以看出生成树是将原图的全部顶点以最少的边连通的子图,对于有n个顶点的连通图,生成树有n-1条边,若边数小于此数就不可能将各顶点连通,如果边的数量多于n-1条边,必定会产生回路

- 对于一个带权连通图,生成树不同,树中各边上权值总和也不同,权值总和最小的生成树则称为图的最小生成树

三、最小生成树的算法

(1)Prim算法

基本思想:

假设有一个无向带权图G=(V,E),他的最小生成树为MinTree=(V,T),其中V为顶点集合,T为边的集合。

求边的集合T的步骤如下:

①令 U={u0},T={}。其中U为最小生成树的顶点集合,开始时U中只含有顶点u0(u0可以为集合V中任意一项,在开始构造最小生成树时我们从u0出发。(初始化)

②对所有u∈U,v∈(V – U)(其中u,v表示顶点)的边(u,v)中,找一条权值最小的边(u’,v’),将这条边加入到集合T中,将顶点v’加入集合U中。(贪婪的方式,加入集合U外最小权重边及对应点)

③直到将V中所有顶点加入U中,则算法结束,否则一直重复以上两步。

④符号说明:我们用大写字母表示集合,用小写字母表示顶点元素用<>表示两点之间的边

举例:

初始状态U={a}   V={b,c,d,e }   T={}

Image

 ⑵集合U和V相关联的权值最小的边是<a,b>,于是我们将b加入U。U={a,b},V={d,c,e },T={<a,b>}

Image

 

 ⑶此时集合U和V相关联的权值最小的边是<b,c>,于是我们将c加入U。U={a,b,c} ,V={d,e },T={<a,b>, <b,c>}

Image

 

显然此时集合U和V中相关联的权值最小的边是<c,d>,于是我们将d加入U。U={a,b,c,d} ,V={e },T={<a,b>, <b,c>,<c,d>} 

Image

 

⑸最后集合U和V中相关联的权值最小的边是<d,e>,于是将e加入U。U={a,b,c,d,e} ,V={},T={<a,b>, <b,c>,<c,d>,<d,e>}

到此所有点访问完毕。

Image

(2)Kruskal算法

Kruskal算法比Prim算法更直观

Kruskal算法的做法是:每次都从剩余边中选取权值最小的,当然,这条边不能使已有的边产生回路。手动求解会发现Kruskal算法异常简单,

例子:

Image

先对边的权值排序

1(V0,V4)、2(V2,V6)、4(V1,V3)、6(V1,V2)、8(V3,V6)、10(V5,V6)、12(V3,V5)、15(V4,V5)、20(V0,V1)

 

首选边1(V0,V4)、2(V2,V6)、4(V1,V3)、6(V1,V2),此时的图是这样

Image

显然,若选取边8(V3,V6)则会出现,则必须抛弃8(V3,V6),选择下一条10(V5,V6)没有问题,此时图变成这样

Image

显然,12(V3,V5)同样不可取,选取15(V4,V5),边数已达到要求,算法结束。最终的图是这样的

Image

算法逻辑很容易理解,但用代码判断当前边是否会引起环的出现则很棘手

这里简单提一提连通分量

无向图,如果从顶点vi到顶点vj有路径,则称vi和vj连通。如果图中任意两个顶点之间都连通,则称该图为连通图,否则,将其中较大的连通子图称为连通分量

有向图,如果对于每一对顶点vi和vj,从vi到vj和从vj到vi都有路径,则称该图为强连通图;否则,将其中的极大连通子图称为强连通分量

【算法说明】

    为了判断环的出现,我们换个角度来理解Kruskal算法的做法:初始时,把图中的n个顶点看成是独立的n个连通分量,从树的角度看,也是n个根节点。选边的标准是这样的:若边上的两个顶点从属于两个不同的连通分量,则此边可取,否则考察下一条权值最小的边。

  于是问题又来了,如何判断两个顶点是否属于同一个连通分量呢?这个可以参照并查集的做法解决。它的思路是:如果两个顶点的根节点是一样的,则显然是属于同一个连通分量这也同样暗示着:在加入新边时,要更新父节点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值