一、什么叫最小生成树

一个无向连通图G=(V,E),最小生成树就是联结所有顶点的边的权值和最小时的子图T,此时T无回路且连接所有的顶点,所以它必须是棵树。

二、为什么要研究最小生成树问题

《算法导论》上举了电子线路设计的例子。而在经济学、生物学中也常应用最小生成树。

三、如何求一个无向连通图的最小生成树

《算法导论》中提取讲解了两种得到最小生成树的算法,一是Kruskal算法,另一种是Prim算法。这两种算法都使用了贪心策略。

先说明几个概念:

安全边:A是G的某最小生成树的子集,如果AU{(u,v)}仍是G的某最小生成树的子集,则(u,v)是安全边;

割:无向图G=(V, E)对V一个划分(S, V-S);

边(u,v)通过割(S,V-S):(u,v)一个顶点位于S中,另一个顶点位于V-S中;

不妨害A的割:A中没有任意一条边通过该割;

轻边(light edge):通过割的所有边中权值最小的(可能有多条)。

生成最小生成树的基本代码结构是:

  1. GENERIC-MST(G, w)
  2. A=空集
  3. while A does not form a spanning tree
  4. do find an edge(u,v) that is safe for A
  5. A=AU{(u,v)}
  6. return A

于是关键就在于找安全边。

定理(《算法导论》中定理23.1)(以白话阐述):G=(V,E) 是个无向连通加权图。A 是 E 的一个子集,它包含于 G 的某个最小生成树中。设割 (S, V-S) 是G的任意一个不妨害A的割(就是说A中任何一条边的两个端点要么全在S中,要么全在V-S中),边(u,v)是通过割(S,V-s)的一条轻边(就是说(u,v)是所有端点分布于S和V-S的边中权值最小的),则(u,v)对集合A是安全的。

推论:A是G=(V,E)的某个最小生成树的子集。G(A)=(V,A)是图G的一个森林(只有A集合中的边),C=(Vc, Ec)为G(A)的一个连通分支(森林中的树)。如果边(u,v)是连接C和G(A)中其他某连通分支的一条轻边,则(u,v)对集合A来说是安全的。

1. Kruskal 算法

  1. MST-KRUSKAL(G, w)
  2. A=空集
  3. for each vertex v∈V[G]
  4. do MAKE_SET(v)
  5. sort the edges of E into nondescreasing order by weight w
  6. for each edge(u,v)∈E, take in nondescreasing order by weight
  7. do if FIND-SET(u) != FIND-SET(v)                              // 如果u和v不在同一个连通分支中,就把(u,v)加入,由推论可知此边是安全的
  8. then A = AU{(u,v)}
  9. UNION(u,v)
  10. return A

FIND-SET(u)是找出u所在的连通分支。

Kruskal在全局中找权值最小的边,然后判断此边是否“合法”,进行取舍,直到遍历完所有的边。

Kruskal算法的运行时间为O(ElgV)。

2. Prim算法

  1. MST-PRIM(G, w, r)
  2. for each u∈V[G]
  3. do key[u]=∞
  4. π(u) = NIL     // π(u)是u的前趋
  5. key[r] = 0
  6. Q=V[G]
  7. while Q != 空集
  8. do u=EXTRACT-MIN(Q)
  9. for each v∈Adj[u]
  10. do if v∈Q and w(u,v)<key[v]
  11. then π(v)=u
  12. key[v] = w(u,v)       // 更新key[v]

Q是一个优先队列,key[v]是所有将v与树中某一顶点相连的边中的最小权值,若不存在这样的边,则k[v]=∞。

Prim算法在局部寻找权值小的的边(此边必合法),直到遍历完所有的节点。

Prim算法的运行时间为O(ElgV),与Kruskal算法渐近相等。

Prim算法实际上使用了与Dijkstra算法同样的策略,维护了一个权值数组key,在迭代过程中不断的更新。

《算法导论》学习总结 — XX.第23章 最小生成树的更多相关文章

  1. 算法导论学习---红黑树具体解释之插入(C语言实现)

    前面我们学习二叉搜索树的时候发如今一些情况下其高度不是非常均匀,甚至有时候会退化成一条长链,所以我们引用一些"平衡"的二叉搜索树.红黑树就是一种"平衡"的二叉搜 ...

  2. 算法导论学习-Dynamic Programming

    转载自:http://blog.csdn.net/speedme/article/details/24231197 1. 什么是动态规划 ------------------------------- ...

  3. 《算法导论》学习总结 — XX.第22章 图的基本算法

    BFS(广搜): 广搜就是广度优先搜索,根据名字可以知道,是通过广度来遍历图,也就是层次遍历吧. 在这里以及下面的DFS(深搜),都用到了颜色WHITE,GRAY,BLACK,不过作用不同,具体分别再 ...

  4. 算法导论学习-RED-BLACK TREE

    1. 红黑树(RED-BLACK TREE)引言: ------------------------------------- 红黑树(RBT)可以说是binary-search tree的非严格的平 ...

  5. 算法导论学习-prim算法

    一. 关于最小生成树 对于无向连通图G=(V,E),其中V表示图的顶点,E表示图的边,对于每条边都有一个权值,可以理解为边a->b的权值C为从a走到b要走的路程为C.现在我们希望找到一个无回路的 ...

  6. 算法导论学习-binary search tree

    1. 概念: Binary-search tree(BST)是一颗二叉树,每个树上的节点都有<=1个父亲节点,ROOT节点没有父亲节点.同时每个树上的节点都有[0,2]个孩子节点(left ch ...

  7. 算法导论学习-heapsort

    heap的定义:如果数组a[1,....n]满足:a[i]>a[2*i] && a[i]>a[2*i+1],1<=i<=n/2,那么就是一个heap,而且是ma ...

  8. 算法导论学习之线性时间求第k小元素+堆思想求前k大元素

    对于曾经,假设要我求第k小元素.或者是求前k大元素,我可能会将元素先排序,然后就直接求出来了,可是如今有了更好的思路. 一.线性时间内求第k小元素 这个算法又是一个基于分治思想的算法. 其详细的分治思 ...

  9. 算法导论学习笔记1---排序算法(平台:gcc 4.6.7)

    平台:Ubuntu 12.04/gcc 4.6.7 插入排序 #include<vector> #include <algorithm> #include<iostrea ...

随机推荐

  1. macaca 测试web(3)

    上回书说到 macaca 测试web(2)  使用ddt做参数驱动化, 有些人会说,你好low,我说怎么low呢,他说你看看你的脚本就放在一个文件里,对于我们小白来说,这看起来很乱啊,能不能给我拆分, ...

  2. 深入浅出数据结构C语言版(16)——插入排序

    从这一篇博文开始,我们将开始讨论排序算法.所谓排序算法,就是将给定数据根据关键字进行排序,最终实现数据依照关键字从小到大或从大到小的顺序存储.而这篇博文,就是要介绍一种简单的排序算法--插入排序(In ...

  3. 文档API生成神器SandCastle使用心得

    一.功能描述 关于Sandcastle网上的参考资料相对较少,Google出来很多资料都是全英文的,相对于我这种英语渣渣看起来还是很费劲的. 言简意赅,Sandcastle主要功能是能够将C#类生成类 ...

  4. 关于 ThinkPHP 在 Nginx 服务器上 使用U方法跳转问题

    这个问题已多次遇到,关于tp 框架 使用U 方法跳转, 在Nginx 服务器上可能会遇到路由跳转不过去前面带点(如:./xx) 解决这个问题,可以在tp的入口文件 index.php 里定义个常量 d ...

  5. https加密实现

    author:JevonWei 版权声明:原创作品 在httpd安装完成的基础上实现https加密 安装mod_ssl软件包 yum -y install mod_ssl http -M 显示mod_ ...

  6. Linux-ps命令(7)

    名称:ps(process status) 使用权限:所有使用者说明:显示瞬间进程 (process) 的动态 示例: 比如输入ps查看进程,如下图: 其中输出状态栏参数: PID 该 process ...

  7. 图片懒加载Demo

    相关知识: [js获取元素位置+元素大小]全面总结

  8. poj 3694双联通缩点+LCA

    题意:给你一个无向连通图,每次加一条边后,问图中桥的数目. 思路:先将图进行双联通缩点,则缩点后图的边就是桥,然后dfs记录节点深度,给出(u,v)使其节点深度先降到同一等级,然后同时降等级直到汇合到 ...

  9. Centos7 & Docker & Jenkins & ASP.NET Core 2.0 自动化发布和部署

    写在前面 Docker一直很火热,一直想把原本的Jenkins自动部署工具搬到Docker上面,无奈今年一直忙于各种事情,迟迟未实施这个事情,正好迎来了dotnet core 2.0 的正式发布,升级 ...

  10. Httprequest 获取url 常用方法

    HttpServletRequest常用获取URL的方法         1.request.getRequestURL() 返回的是完整的url,包括Http协议,端口号,servlet名字和映射路 ...