) {0 d# N$ o' `" S(iv)G 是树当且仅当G 连通,且∀e∈ E(G) ,G − e 不连通。 ! n2 }9 v! N8 b9 c* U M; u' C' t
(v)G 是树当且仅当G 无圈,∀e∉ E(G) ,G + e 恰有一个圈。% j& s s& H+ c+ Y" x) e3 U5 O* p
# M" ^7 y0 S8 c* }% u" i |' s5 V2.1 prim 算法构造最小生成树+ P1 P: S i, o+ X( \4 H
设置两个集合 P 和Q ,其中 P 用于存放G 的最小生成树中的顶点,集合Q 存放G的最小生成树中的边。令集合 P 的初值为 { P = v1 }(假设构造最小生成树时,从顶点 v1 出发),集合Q 的初值为Q = Φ 。( `4 x0 ~4 a9 W% w" T
o8 w, F& A: p* t8 D! u, k, }prim 算法的思想是,从所有 p ∈ P ,v ∈V − P 的边 中,选取具有最小权值的边 pv ,将顶点 v 加入集合 P 中,将边 pv 加入集合Q 中,如 此不断重复,直到 P =V 时,最小生成树构造完毕,这时集合Q 中包含了最小生成树 的所有边。0 |# ]) e. H' [ ( z7 ?' b( Q+ e6 J8 g$ F: _* v T1 p) k2 d
, J q R E1 }例 13 用 prim 算法求图 5 的最小生成树。 我们用 的第一、二、三行分别表示生成树边的起点、终点、权集合。Matlab 程序如下:5 \& [6 G. h5 O
" x" R M$ @/ ` n$ n+ v
% e2 y6 h+ k: G3 c8 F, w
clc;clear; : A$ e6 Q; X. z. na=zeros(7); $ u7 k7 q0 ~$ y- p0 l- Z0 Ca(1,2)=50; a(1,3)=60; ~% q9 K; B# b' ]
a(2,4)=65; a(2,5)=40;3 m% `, [5 d4 N4 d
a(3,4)=52;a(3,7)=45; % D6 Q/ @5 z4 ~3 C ?/ D! ra(4,5)=50; a(4,6)=30;a(4,7)=42; ) T F3 p- r2 D; [. x1 t3 Ya(5,6)=70; 9 m% ~" T+ ^" N& } J% Ba=a+a';a(find(a==0))=inf;& @. }/ ~0 ?) ?5 j* r# M& n6 p
result=[];p=1;tb=2:length(a);3 W9 {" P! {. F8 f2 x$ W0 P$ y
while length(result)~=length(a)-1 " c1 z' q9 B9 s9 [% N- ]9 X7 l temp=a(p,tb);temp=temp(;4 U/ V" F8 {* Z! N4 P8 {
d=min(temp);: J+ e/ I+ N2 J, l( Q* V
[jb,kb]=find(a(p,tb)==d);! k( {, t) J. f
j=p(jb(1));k=tb(kb(1));: h- `2 c. a# E7 K" H
result=[result,[j;k;d]];p=[p,k];tb(find(tb==k))=[]; " Y- \5 f2 n8 j$ {' u% ]end) V9 z& R8 |4 G9 F% S
result) ?$ O! ^9 e3 P4 }; ~: H
- j8 I2 b+ A- a
2.1 Kruskal 算法构造最小生成树 7 Q* Z0 h1 h3 ?. l科茹斯克尔(Kruskal)算法是一个好算法。Kruskal 算法如下:- L( H3 r( O, D3 D0 y # `9 L' c5 A3 Z8 r5 @; _& J) p& P. I2 U. S