- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
应用举例——最小生成树
最小生成树
生成树是一个连通图G的一个极小连通子图。包含G的所有n个顶点,但只有n-1条边,并且是连通的。
当生成树中所包含的边的权值和最小,我们称之为最小生成树。
最小生成树性质
最小生成树的边数必然是顶点数减一,|E| = |V| - 1。
最小生成树不可以有循环。
最小生成树不必是唯一的。
本节所介绍的2种最小生成树算法,都是基于贪心策略。
I.Kruskal算法
II.Prim算法
克鲁斯卡尔(Kruskal)算法
基本思想:
假设 WN=(V,{E}) 是一个含有 n 个顶点的连通网,则按照克鲁斯卡尔算法构造最小生成树的过程为:先构造一个只含 n 个顶点,而边集为空的子图,若将该子图中各个顶点看成是各棵树上的根结点,则它是一个含有 n 棵树的一个森林。之后,从网的边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,也就是说,将这两个顶点分别所在的两棵树合成一棵树;反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。依次类推,直至森林中只有一棵树,也即子图中含有 n-1条边为止。
应用举例——最小生成树
Kruskal 算法过程
b
c
h
i
f
a
e
d
g
4
8
8
4
14
7
9
10
6
7
2
11
a
i
d
c
b
h
g
f
e
1
2
两点属于同一颗树
两点属于同一颗树
两点属于同一颗树
当森林只剩下一棵树时,算法结束
#includeiostream
#includealgorithm
using namespace std;
struct Edge
{
int a,b;//边的两个顶点的编号
int d;//边的权值
}edge[11111];
int n,m,s;//n为无向图的顶点个数,m为边的条数,s用来存放最小生成树的总权值
int root[111];//存储父节点
bool cmp(Edge a,Edge b)
{
return a.db.d;
}
int find(int a)//寻找父节点
{
if(root[a]==a) return a;
return root[a]=find(root[a]);
}
bool Union(int a,int b,int d)//合并
{
if(a==b) return 0;//a==b说明边的两个顶点一属于同一颗树,
所以不需要合并,直接返回
root[a]=b;//将a的父节点更新为b,从而将树a,b合并成一棵树
s+=d;//将边的权值加到s当中
return 1;
}
void kruskal()
{
for(int i=0;in;i++)//初始化,将各顶点的父节点标记为本身
root[i]=i;
sort(edge,edge+m,cmp);//将所有边 根据边的权值 从小到大排列
s=0;
for(i=0;im;i++)//遍历所有的边
{
if(Union(find(edge[i].a),find(edge[i].b),edge[i].d))
n--;//当合并成功,森林的树就少一棵
}//当遍历完所有的边时,如果n!=1,说明该无向图不是连通图,不存在最小生成树
}
MST性质
假设G=(V, E)是一个无向连通网,U是顶点集V的一个非空子集。若(u, v)是一条具有最小权值的边,其中u∈U,v∈V-U,则必存在一棵包含边(u, v)的最小生成树。
应用举例——最小生成树
10
MST性质
假设G=(V, E)是一个无向连通网,U是顶点集V的一个非空子集。若(u, v)是一条具有最小权值的边,其中u∈U,v∈V-U,则必存在一棵包含边(u, v)的最小生成树。
应用举例——最小生成树
11
基本思想:设G=(V, E)是具有n个顶点的连通网,T=(U, TE)是G的最小生成树,T的初始状态为U={u0}(u0∈V),TE={ },重复执行下述操作:在所有u∈U,v∈V-U的边中找一条代价最小的边(u, v)并入集合TE,同时v并入U,直至U=V。
普里姆(Prim)算法
应用举例——最小生成树
12
1. 初始化: U={u0}(u0∈V),TE={ };
2. 循环直到U=V为止
2.1 在所有u∈U,v∈V-U的边中找一条代价最小的边(u,v);
2.2 TE=TE+{(u,v)};
2.3 U=U+{v};
关键:是如何找到连接U和V-U的最短边。
普里姆(Prim)算法
应用举例——最小生成树
利用MST性质,可以用下述方法构造候选最短边集:对V-U中的每个顶点,分别求其到U的最短边。
13
U={
文档评论(0)