生成树的概念:
连通图的生成树是包含图中全部顶点的一个极小连通子图
(边尽可能的少,但要保持连通)
若图中顶点数为n,则它的生成树中含有n-1条边。对于生成树而言,若看去他的一条边,则会变成非连通图,若加上一条边则会形成一个回路。
下面我们介绍最小生成树(无向图)
也叫最小代价树
从带权连通图找出来,最小代价的生成树。
对于一个带权连通无向图G=(V,E),生成树不同,每棵树的权(即树中所有边的权值之和)也可能不同。
设R为G的所有生成树的集合
若T为R中边的权值之和最小的生成树,则T称为G的最小生成树(Minimum-Spanning-Tree)
(1)最小生成树可能有多个,但边的权值之和总是唯一且是最小的
(2)最小生成树的边数=顶点数-1(砍掉一条则不连通,增加一条则出现回路)
一,prim算法(普里姆)
从某一个顶点开始构建生成树:
每次将代价最小的新顶点纳入生成树,直到所有顶点都纳入为止。
从P城这个节点开始:
得到了最小生成树,最小代价为:15
我们退一退,如果选择下面这条边
所以说同一个图可能是会有两个最小生成树
刚才我们从P城结点开始,现在我们从农场节点试验Prim算法。
最小代价依然是15.
二,Kruskal算法(克鲁斯卡尔)
每次选择一条权值最小的边,使这条边的两头连通(原本已经的就不选)
直到所有的节点都连通
P城和渔村这两个节点已经联通
算法到此结束
一,prim算法的实现思想
与v0相互连接的边v1v2v3
因为加入了v3这个节点,我们需要更新lowcast值。
找到这个结点到这个连通分量的最低代价:
这样就完成了第一轮的处理
再来看Kruskal算法的实现思想:
我们需要做这样一个预处理:
不连通,就连起来
这两个顶点就成为了同一个集合
下个权值最小的边是v2和v5 ,也不连通,把他们连起来。
下一个权值最小为v1,v4不连通,连起来
v2和v3从属于不同的集合。
此时v3和v5已经从属于一个集合了,我们需要跳过他。
并查集的判断:两个顶点是否从属于一个集合。