图的应用
最小生成树
1.最小生成树的概念
若从图的某顶点出发,可以系统地访问到图中所有顶点,则遍历时经过的边和图的所有顶点所构成的子图,称作该图的生成树。(此定义不仅仅适用于无向图,对有向图同样适用。)
(1)若G是强连通的有向图,则从其中任一顶点v出发,都可以访问遍G中的所有顶点,从而得到以v为根的生成树。
(2)若G是有根的有向图,设根为v,则从根v出发可以完成对G的遍历,得到G的以v为根的生成树。
构造生成树有两种方法,即深度优先生成树和广度优先生成树。
所谓深度优先生成树,使用深度优先搜索方法遍历一个连通图,所经过的边和顶点构成一棵树。
广度优先生成树是指使用深度优先搜索方法遍历一个连通图,所经过的边和顶点构成一棵树。
图6-12 (a)、(b)所示的均为图6-11(a)的无向连通图的深度优先生成树和广度优先生成树。
(a) 深度优先生成树 (b) 广度优先生成树
图6-12 无向连通图g的两棵生成树
如果无向连通图是一个网,那么,它的所有生成树中必有一棵边的权值总和最小的生成树,我们称这棵生成树为最小生成树,简称为最小生成树(也称最小代价生成树) 。
最小生成树的概念可以应用到许多实际问题中。例如有这样一个问题:以尽可能抵的总造价建造城市间的通讯网络,把十个城市联系在一起。在这十个城市中,任意两个城市之间都可以建造通讯线路,通讯线路的造价依据城市间的距离不同而有不同的造价,可以构造一个通讯线路造价网络,在网络中,每个顶点表示城市,顶点之间的边表示城市之间可构造通讯线路,每条边的权值表示该条通讯线路的造价,要想使总的造价最低,实际上就是寻找该网络的最小生成树。
下面介绍两种常用的构造最小生成树的方法。
2.构造最小生成树的Prim算法
假设G=(V,E)为一网图,其中V为网图中所有顶点的集合,E为网图中所有带权边的集合。设置两个新的集合U和T,其中集合U用于存放G的最小生成树中的顶点,集合T存放G的最小生成树中的边。令集合U的初值为U={u1}(假设构造最小生成树时,从顶点u1出发),集合T的初值为T={}。Prim算法的思想是,从所有u∈U,v∈V-U的边中,选取具有最小权值的边(u,v),将顶点v加入集合U中,将边(u,v)加入集合T中,如此不断重复,直到U=V时,最小生成树构造完毕,这时集合T中包含了最小生成树的所有边。
Prim算法可用下述过程描述,其中用wuv表示顶点u与顶点v边上的权值。
(1)U={u1},T={};
(2)while (U≠V)do
(u,v)=min{wuv;u∈U,v∈V-U }
T=T+{(u,v)}
U=U+{v}
(3)结束。
图6-13 (a)所示的一个网图,按照Prim方法,从顶点1出发,该网的最小生成树的产生过程如图6-13(b)、(c)、(d)、(e)、(f)和(g)所示。50 40 55 42 32 35 30 40 20 60
(a) (b) (c)
(d) (e) (f)
(g) (h)
图6-13 Prim算法构造最小生成树的过程示意
3.构造最小生成树的Kruskal算法
Kruskal算法是一种按照网中边的权值递增的顺序构造最小生成树的方法。其基本思想是:设无向连通网为G=(V,E),令G的最小生成树为T,其初态为T=(V,{}),即开始时,最小生成树T由图G中的n个顶点构成,顶点之间没有一条边,这样T中各顶点各自构成一个连通分量。然后,按照边的权值由小到大的顺序,考察G的边集E中的各条边。若被考察的边的两个顶点属于T的两个不同的连通分量,则将此边作为最小生成树的边加入到T中,同时把两个连通分量连接为一个连通分量;若被考察边的两个顶点属于同一个连通分量,则舍去此边,以免造成回路,如此下去,当T中的连通分量个数为1时,此连通分量便为G的一棵最小生成树。
对于图6-14(a)所示的网,按照Kruskal方法构造最小生成树的过程如图6-15所示。在构造过程中,按照网中边的权值由小到大的顺序,不断选取当前未被选取的边集中权值最小的边。依据生成树的概念,n个结点的生成树,有n-1条边,故反复上述过程,直到选取了n-1条边为止,就构成了一棵最小生成树。
(a) (b) (c)
(d) (e) (f)
图6-14 Kruskal算法构造最小生成树的过程示意