数据结构15--最小生成树PPT课件
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
.
北极通讯网络
北极的某区域共有n座村庄(1n500),每座村庄的坐标用一对整 数(x,y)表示,其中 0x,y10000。为了加强联系,决定在村庄 之间建立通讯网络。通讯工具可以是无线电收发机,也可以是卫星设 备。所有的村庄都可以拥有一部无线电收发机, 且所有的无线电收 发机型号相同。但卫星设备数量有限,只能给一部分村庄配备卫星设 备。不同型号的无线电收发机有一个不同的参数d,两座村庄之间的 距离如果不超过d就可以用该型号的无线电收发机直接通讯,d值越 大的型号价格越贵。拥有卫星设备的两座村庄无论相距多远都可以直 接通讯。
.
fillchar(ba,sizeof(ba),0); /*所有顶点未在生成树*/
for i←2 to n do d[i]←∞; /*所有Leabharlann Baidu点的距离值初始化*/
d[1]←0 ;ans←0;/*顶点1的距离值和生成树的权和初始化*/
for i←1 to n do /*依次范围每个顶点*/
{ min←maxint;/*在所有未在生成树、且距离值最小(min)的顶点 k*/
/*顶点数
f:Array [1..maxn] of longint;
/*并查集。其
中f[i]为顶点i所在并查集的代表顶点,即子树根*/
.
通过函数top(i)计算顶点i所在子树的根
func top(i:longint):longint; /*计算和返回顶点i所在并查集的代表顶点*/ { if i<>f[i] Then f[i]←top(f[i]); /*若i非所在并查集的代表顶点,则沿f[i]递归 */
Type
edgetype=Record
/*边的类型*/
为c的边(x,y)*/
x,y,c:longint;
/*边权
end;
Var
e:Array [1..maxe] of edgetype;
/*边集,其中第i条
边为(e[i].x,e[i].y),该边的权为e[i].c*/
n,m,ans:longint; 为n,边数为m*/
Writeln(ans);
显然, Kruskal算法的效率取决于边数m,因此适用与
稀疏图。
.
②、Prim算法
集合A中的边总是只形成单棵树,每次添加到 树中的边都是使树的权尽可能小的边。
.
设 d[i]—顶点i与生成树相连的最短边长; ba[i]—顶点i在生成树的标志; w[i,j]—(i,j)的边长。若图中不存在边 (i,j),则w[i,j]=∞ min—所有未在生成树的顶点的最小距离 值
有两种算法可计算图的最小生成树 ①、Kruskal算法 ②、Prim算法
.
①、Kruskal算法
找出森林中连结任意两棵树的所有边中具有最小权值的边(u,v) 作为安全边,并把它添加到正在生长的森林中。初始时,森林 由单个结点组成的n棵树。
.
Kruskal程序
Const
maxn=200; maxe=maxn*maxn; /*顶点数和边数的上限*/
top←f[i]; /*返回顶点i所在并查集的代表 顶点*/ };/*top*/
.
通过过程Union(i,j,c)合并顶点i和顶点j所 在的两棵树
现有边权为c的边(i,j)。若该边的两个端点 分属于两棵树,顶点i和顶点j所在子树的根分别 为x和v,则(i,j) 加入最小生成树,合并两棵树 (即顶点i和顶点j所在的并查集)。
图的最小生成树
对于一张图进行深度优先搜索或宽 度优先搜索,可生成一棵深度优先 搜索树或宽度优先搜索树。搜索的 出发点不同,生成树的形态亦不同。 在一张有权连通图中,各边权和为 最小的一棵生成树即为最小生成树。
.
计算最小生成树的思维方向:为了保证边权 总和最小,必须保证
①、添加(u,v)不能够形成回路、 ②、在保证1的前提下添加权尽可能小的, 这样的边称之为安全边
};/* Union */
.
主算法
按照边权值(c域值)递增的顺序排序边集e;
For i←1 to n Do f[i]←i; /*建立由n棵树组成的 森林,每棵树包含图的一个顶点*/
ans←0; 始化为0*/
/* 最小生成树的权和初
For i←1 to m Do Union(e[i].x,e[i].y,e[i].c); /*枚举每条边,将两个端点分属两棵树的边加入最小生 成树*/
for j←1 to n do
if not ba[j]and(d[j]<min) then { k←j;min←d[j] }; /*then*/
if min= maxint then { ans←-1;break;};/*若这样的顶点不存 在,则无解退出*/
ans←ans+min;ba[k]←true;/*最小距离值min计入生成树的权和, 顶点k进入生成树*/
proc Union(i,j,c:longint); /*合并i和j所在集合 */
Var x,y:longint;
{ x←top(i); y←top(j); 点j所在子树的根*/
/*分别取出顶点i和顶
if x<>y Then { inc(ans,c);f[y]←x;}; /*若i 和j分属于两棵子树,则该边权计入最小生成树的权和, 两棵子树合并*/
树之间 添安全边;Prim算法 在单棵树上添安全边。 Kruskal算法的效率取决于边数 m,因此适用于稀疏图; Prim 算法的效率取决于顶点数n, 因此适用于稠密图
.
计算最大边权最小的生成树
给出一个有边权的图,要求其中的一棵 生成树,使得这棵生成树的最大边权最 小。
.
图的最小生成树满足这个性质
for j←1 to n do 的距离值*/
/*调整与k相连的各顶点
{ min←w[k,j];if min<d[j] then d[j]←min };/*for*/
};/*for*/
writeln(ans:0:3); /*输出最小生成树的权和*/
.
两种算法的比较
共同点:贪心,选择边权最小的安全边 不同点: Kruskal算法在森林中的两 棵
反证法:反设图中存在一棵生成树T,T中的最大边权 小于最小生成树Tmin的最大边权。
令e是Tmin的最大边。e将Tmin分成两个连通分块X和Y。 由于Tmin是最小生成树,那么图中连接X和Y的任意边e’, 其边权都大于等于e的边权——结论1。
而T是图的一棵生成树,那么T中的最大边e’’连接X和 Y,按照假设,e’’的边权小于e的边权。这与结论1矛盾, 因此最小生成树最大边权最小的结论是成立的。 因此只要用Prim或Kruscarl算法求出图的最小生成树 即可。
北极通讯网络
北极的某区域共有n座村庄(1n500),每座村庄的坐标用一对整 数(x,y)表示,其中 0x,y10000。为了加强联系,决定在村庄 之间建立通讯网络。通讯工具可以是无线电收发机,也可以是卫星设 备。所有的村庄都可以拥有一部无线电收发机, 且所有的无线电收 发机型号相同。但卫星设备数量有限,只能给一部分村庄配备卫星设 备。不同型号的无线电收发机有一个不同的参数d,两座村庄之间的 距离如果不超过d就可以用该型号的无线电收发机直接通讯,d值越 大的型号价格越贵。拥有卫星设备的两座村庄无论相距多远都可以直 接通讯。
.
fillchar(ba,sizeof(ba),0); /*所有顶点未在生成树*/
for i←2 to n do d[i]←∞; /*所有Leabharlann Baidu点的距离值初始化*/
d[1]←0 ;ans←0;/*顶点1的距离值和生成树的权和初始化*/
for i←1 to n do /*依次范围每个顶点*/
{ min←maxint;/*在所有未在生成树、且距离值最小(min)的顶点 k*/
/*顶点数
f:Array [1..maxn] of longint;
/*并查集。其
中f[i]为顶点i所在并查集的代表顶点,即子树根*/
.
通过函数top(i)计算顶点i所在子树的根
func top(i:longint):longint; /*计算和返回顶点i所在并查集的代表顶点*/ { if i<>f[i] Then f[i]←top(f[i]); /*若i非所在并查集的代表顶点,则沿f[i]递归 */
Type
edgetype=Record
/*边的类型*/
为c的边(x,y)*/
x,y,c:longint;
/*边权
end;
Var
e:Array [1..maxe] of edgetype;
/*边集,其中第i条
边为(e[i].x,e[i].y),该边的权为e[i].c*/
n,m,ans:longint; 为n,边数为m*/
Writeln(ans);
显然, Kruskal算法的效率取决于边数m,因此适用与
稀疏图。
.
②、Prim算法
集合A中的边总是只形成单棵树,每次添加到 树中的边都是使树的权尽可能小的边。
.
设 d[i]—顶点i与生成树相连的最短边长; ba[i]—顶点i在生成树的标志; w[i,j]—(i,j)的边长。若图中不存在边 (i,j),则w[i,j]=∞ min—所有未在生成树的顶点的最小距离 值
有两种算法可计算图的最小生成树 ①、Kruskal算法 ②、Prim算法
.
①、Kruskal算法
找出森林中连结任意两棵树的所有边中具有最小权值的边(u,v) 作为安全边,并把它添加到正在生长的森林中。初始时,森林 由单个结点组成的n棵树。
.
Kruskal程序
Const
maxn=200; maxe=maxn*maxn; /*顶点数和边数的上限*/
top←f[i]; /*返回顶点i所在并查集的代表 顶点*/ };/*top*/
.
通过过程Union(i,j,c)合并顶点i和顶点j所 在的两棵树
现有边权为c的边(i,j)。若该边的两个端点 分属于两棵树,顶点i和顶点j所在子树的根分别 为x和v,则(i,j) 加入最小生成树,合并两棵树 (即顶点i和顶点j所在的并查集)。
图的最小生成树
对于一张图进行深度优先搜索或宽 度优先搜索,可生成一棵深度优先 搜索树或宽度优先搜索树。搜索的 出发点不同,生成树的形态亦不同。 在一张有权连通图中,各边权和为 最小的一棵生成树即为最小生成树。
.
计算最小生成树的思维方向:为了保证边权 总和最小,必须保证
①、添加(u,v)不能够形成回路、 ②、在保证1的前提下添加权尽可能小的, 这样的边称之为安全边
};/* Union */
.
主算法
按照边权值(c域值)递增的顺序排序边集e;
For i←1 to n Do f[i]←i; /*建立由n棵树组成的 森林,每棵树包含图的一个顶点*/
ans←0; 始化为0*/
/* 最小生成树的权和初
For i←1 to m Do Union(e[i].x,e[i].y,e[i].c); /*枚举每条边,将两个端点分属两棵树的边加入最小生 成树*/
for j←1 to n do
if not ba[j]and(d[j]<min) then { k←j;min←d[j] }; /*then*/
if min= maxint then { ans←-1;break;};/*若这样的顶点不存 在,则无解退出*/
ans←ans+min;ba[k]←true;/*最小距离值min计入生成树的权和, 顶点k进入生成树*/
proc Union(i,j,c:longint); /*合并i和j所在集合 */
Var x,y:longint;
{ x←top(i); y←top(j); 点j所在子树的根*/
/*分别取出顶点i和顶
if x<>y Then { inc(ans,c);f[y]←x;}; /*若i 和j分属于两棵子树,则该边权计入最小生成树的权和, 两棵子树合并*/
树之间 添安全边;Prim算法 在单棵树上添安全边。 Kruskal算法的效率取决于边数 m,因此适用于稀疏图; Prim 算法的效率取决于顶点数n, 因此适用于稠密图
.
计算最大边权最小的生成树
给出一个有边权的图,要求其中的一棵 生成树,使得这棵生成树的最大边权最 小。
.
图的最小生成树满足这个性质
for j←1 to n do 的距离值*/
/*调整与k相连的各顶点
{ min←w[k,j];if min<d[j] then d[j]←min };/*for*/
};/*for*/
writeln(ans:0:3); /*输出最小生成树的权和*/
.
两种算法的比较
共同点:贪心,选择边权最小的安全边 不同点: Kruskal算法在森林中的两 棵
反证法:反设图中存在一棵生成树T,T中的最大边权 小于最小生成树Tmin的最大边权。
令e是Tmin的最大边。e将Tmin分成两个连通分块X和Y。 由于Tmin是最小生成树,那么图中连接X和Y的任意边e’, 其边权都大于等于e的边权——结论1。
而T是图的一棵生成树,那么T中的最大边e’’连接X和 Y,按照假设,e’’的边权小于e的边权。这与结论1矛盾, 因此最小生成树最大边权最小的结论是成立的。 因此只要用Prim或Kruscarl算法求出图的最小生成树 即可。