贪心算法——最小生成树
贪心算法——最小生成树
何为最小生成树:
如图:
通俗一点呢 就是能连通图上所有点的一条不存在环的权重总和最小的路径
求最小生成树的两种算法
1.Kruskal算法
(1)流程
a.初始化:将图\(G=<V,E>\)初始化只有n个独立顶点的图,并按边权重从小到大排序;
b.依次遍历排序好的边,如果边\(e_{ij}\)的两个顶点\(v_i\)和\(v_j\)属于两个不同的连通分支,则将此边加入到图中,否则忽略该边。
如图
(2)割性质及其证明
此证明运用了反证法
(3)Kruskal算法具有最优子结构性质
Kruskal算法每次选择一条边e将两个不连通的图\(T_1\)和\(T_2\)连成一棵树T,设T是最小生成树,则\(T_1\)和\(T_2\)是它们节点集合的最小生成树。
证明:
通过反证法进行证明,假设\(T'_1\)(或者\(T'_2\))是\(T_1\)(或者\(T_2\))节>点集合的最小生成树,用边e将这两个不连通图\(T'_1\)和\(T'_2\)连成一个树>\(T'\)时:\[W(T') =W(T'_1)+W(T'_2)+w_e<W(T_1)+W(T_2)+w_e=W(T) \]这与\(T\)是最小生成树矛盾,引理得证。
Prim算法
(1)初始化:所有节点的\(weight\)值置为\(\infty\),\(prev\)值设为\(null\),选择任意节点作为根节点,跟节点的\(weight\)值置为0,\(prev\)值为自身,并将根节点放入\(T\)中(最终\(T\)为最小生成树),并将根节点设为当前节点。
(2)将所有和当前节点直接相连的节点\(weight\)进行更新,即如果当前节点相连的边的权重小于节点\(weight\)值,则更新,且将\(prev\)值设为当前节点,否则,不进行更新;
(3)在剩余节点(未加入到树中),选择一个\(weight\)值最小的节点加入到\(T\)中,并将此节点作为当前节点;
(4)重复步骤(2)和(3),直到所有的节点都加入到\(T\)中。
流程如图