minimum spanning tree(MST)

最小生成树是连通无向带权图的一个子图,要求

能够连接图中的所有顶点、无环、路径的权重和为所有路径中最小的.

graph-cut

对图的一个切割或者叫切断,会使图分离成为两个不相连的顶点集.

它基于树的两个基本属性:

为树的任意两个节点间添加一条边,会在树中形成一个环.

删去树中的一条边,会将原树分离成两棵不相连的树.

crossing edge

有了切断的概念,很容易就会问到,被切开的那些边是什么?

切断造成了两个不相连的顶点集,而切断的操作施加在这些边上,那么这些边本身就横跨了两个顶点集.

prim’s algorithm

最常用的一种求MST的算法是普利姆算法

它是一种贪心算法.

它搜索的方向是从某一个顶点开始,对所有邻接的边进行考察,然后将最轻的边(权重最小的边)加入MST.

决定它下一步搜索方向的,是最轻边的另一端的顶点,从这个顶点开始,它重复上一步,直到所有的顶点访问完毕.

由于普利姆算法每次都贪心地找当前看来最轻的边,它不会综合考量全局,所以它是一种贪心算法.

由于它从最轻边的另一个端点继续它的搜索之旅,所以每一步求出的在MST中的边都会自然地连成一颗树,直到最后长大为MST.

PriorityQueue

在普利姆算法中,一个重要的操作是挑选最轻边,所以一个优先队列可以对这个操作进行优化支持.

优先队列通常基于堆来实现,比如二叉堆.它可以给我们对数级的时间返回队头元素,而这个队头元素具有最高的优先级.

如果我们规定越轻的边的优先级越高,那么一个小根堆实现的升序优先队列就可以用在普利姆算法中.

lazy prim

普利姆算法在找到一条最轻边(v,w)后,这条边就不应该在以后的搜索中成为一个备选,同时点w也被加入了MST,那么优先队列中所有还未访问的但和点w连着的那些边都成了废弃边,它们不应该被再次考察.

那么如何处理这种不再备选的边?

我们可以删除这些边,但是删除这条边后,边的另一端顶点还没有访问,我们的删除操作会波及那些还没有访问的顶点.

那么,一个比较懒而直观的方式是

推迟对所有的废弃边的删除操作,任由它们在优先队列中,作为队列一员参与队列的每次调整操作.

采取懒惰方式的普利姆算法的时间复杂度是O(ElogE).从这里看出,它对边比较稠密的图来说,是低效的.

如果要了解懒惰方式的的普利姆算法,请参考:普利姆算法lazy实现

eager prim

以懒惰方式处理不再备选的边,会使得算法多次考察这样的边,影响了效率.

有没有方法对它进行改进?

考虑一下,我们在找出一条最轻边并将它加入MST后,实际上使得其它的还没有被访问的边被访问的机会增加了.

而我们只对最轻边感兴趣,所以在考察一个顶点时,只需要在优先队列中维护一条目前已知的到这个顶点的最短距离或最小权重就可以了.

为了不将废弃边加入队列,我们需要以索引方式来组织优先队列.

关于索引式的优先队列,请参考:索引式 优先队列

以积极方式队列废弃边的算法,请参考:普利姆算法eager实现

普利姆算法的eager实现的时间复杂度是最差O(ElogV )

kruskal’s algorithm

克鲁斯卡尔算法是求MST的另一种常用算法,它非常简单:

1.每一步都挑选当前看来最轻的边.如果这条边的两个端点的加入,没有在mst中造成回路,将这条边加入mst.

2.对所有的边重复上一步.

算法中比较关键的一个操作是判断是否形成回路(cycle),这可以借助并查集来做,请参考:快速并查集

克鲁斯卡尔算法的时间复杂度为O(ElogE).

这里是一个完成的算法实现,请参考:克鲁斯卡尔算法实现

综述

最小生成树和最小生成森林(minimum spanning forest)技术,对于连通性考察很有意义.

克鲁斯卡尔算法和懒惰方式的普利姆算法形式简单、易于理解,适合处理边不稠密的图.

积极方式的普利姆算法,初次接触会不易理解.但它效率高于懒惰方式,平均适用性更好.

求MST的贪心算法,都离不开优先队列或堆的支持,堆的操作效率决定了这些算法的效率.

如果用斐波那契堆来实现优先队列,则decrease-key操作的摊还代价是O(1 ),普里姆算法将可优化到:O(E+VlogV ).

说说最小生成树(Minimum Spanning Tree)的更多相关文章

  1. 【算法】关于图论中的最小生成树(Minimum Spanning Tree)详解

    本节纲要 什么是图(network) 什么是最小生成树 (minimum spanning tree) 最小生成树的算法 什么是图(network)? 这里的图当然不是我们日常说的图片或者地图.通常情 ...

  2. 最小生成树(Minimum Spanning Tree)——Prim算法与Kruskal算法+并查集

    最小生成树——Minimum Spanning Tree,是图论中比较重要的模型,通常用于解决实际生活中的路径代价最小一类的问题.我们首先用通俗的语言解释它的定义: 对于有n个节点的有权无向连通图,寻 ...

  3. Prim算法、Kruskal算法和最小生成树 | Minimum Spanning Tree

    graph to tree非常有趣! 距离的度量会极大地影响后续的分析,欧式距离会放大差异,相关性会缩小差异,导致某些细胞群分不开. 先直观看一下,第一个是Prim,第二个是Kruskal.但是肯定都 ...

  4. 算法练习:最小生成树 (Minimum Spanning Tree)

    (注:此贴是为了回答同事提出的一个问题而匆匆写就,算法代码只求得出答案为目的,效率方面还有很大的改进空间) 最小生成树是指对于给定的带权无向图,需要生成一个总权重最小的连通图.其问题描述及算法可以详见 ...

  5. 最小生成树 (Minimum Spanning Tree,MST) --- Prim算法

    本文链接:http://www.cnblogs.com/Ash-ly/p/5409904.html 普瑞姆(Prim)算法: 假设N = (V, {E})是连通网,TE是N上最小生成树边的集合,U是是 ...

  6. 最小生成树 (Minimum Spanning Tree,MST) --- Kruskal算法

    本文链接:http://www.cnblogs.com/Ash-ly/p/5409265.html 引导问题: 假设要在N个城市之间建立通信联络网,则连通N个城市只需要N - 1条线路.这时,自然会考 ...

  7. 【HDU 4408】Minimum Spanning Tree(最小生成树计数)

    Problem Description XXX is very interested in algorithm. After learning the Prim algorithm and Krusk ...

  8. 数据结构与算法分析–Minimum Spanning Tree(最小生成树)

    给定一个无向图,如果他的某个子图中,任意两个顶点都能互相连通并且是一棵树,那么这棵树就叫做生成树(spanning tree). 如果边上有权值,那么使得边权和最小的生成树叫做最小生成树(MST,Mi ...

  9. HDU 4408 Minimum Spanning Tree 最小生成树计数

    Minimum Spanning Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  10. Educational Codeforces Round 3 E. Minimum spanning tree for each edge 最小生成树+树链剖分+线段树

    E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...

随机推荐

  1. ios 个人开发者账户 给其他团队用坑爹的教程

    最新版本的 ios  支持 3个开发者证书 和 3个发布者证书  ,如果是多余3台电脑设备要真机调试,就比较麻烦 (手机支持100个设备) 解决方案就是: 在别人的电脑上要成功安装,须具备两个文件: ...

  2. 关闭linux退格键和vi发出的嘟嘟声

    以root用户登录,然后请安下面方法进行操作: 在命令行下执行:echo "rmmod pcspkr" >> /etc/rc.d/rc.local

  3. yum安装Mysql-5.6

    MySQL yum库提供了一个简单的和方便的方法来安装和更新MySQL相关的软件包到最新版本. MySQL yum库文档说明:http://dev.mysql.com/doc/mysql-yum-re ...

  4. 利用sys.dm_db_index_physical_stats查看索引大小/碎片等信息

    我们都知道,提高sql server的数据查询速度,最有效的方法,就是为表创建索引,而我们对数据表进行新增,删除,修改的时候,会产生索引碎片,索引碎片多了,对性能产生很大的影响,索引碎片越多对数据库查 ...

  5. **后台怎么处理JSON数据中含有双引号?

    http://bbs.csdn.net/topics/390578406?page=1 注意是后台,不是用js另外我这个json是直接取得别人的传过来的字符串,不是我自己拼写的,所以我自己不能做到转义 ...

  6. day1作业:编写登录窗口一个文件实现

    思路: 1.参考模型,这个作业我参考了linux的登录认证流程以及结合网上银行支付宝等锁定规则: 1)认证流程参考的是Linux的登录:当你输入完用户名密码后再验证用户名是否存在用户是否被锁定,然后在 ...

  7. python 判断字符编码

    一般情况下,需要加这个: import sys reload(sys) sys.setdefaultencoding('utf-8') 打开其他文件编码用codecs.open 读 下面的代码读取了文 ...

  8. Wpf使用Winform控件后Wpf元素被Winform控件遮盖问题的解决

    有人会说不建议Wpf中使用Winform控件,有人会说建议使用Winform控件在Wpf下的替代方案,然而在实际工作中由于项目的特殊需求,考虑到时间.成本等因素,往往难免会碰到在WPF中使用Winfr ...

  9. 解决ssh登陆过慢问题

    我们经常会遇到的一个情况是telnet到server速度很快,但是ssh连接的时候却很慢,大概要等半分钟甚至更久.ping的速度也非常好,让人误以为是ssh连接不上. 下面说下如何解决这样的问题,最为 ...

  10. Kibana部署及配置(四)

    一.Kibana安装 Kibana 是为 Elasticsearch 设计的开源分析和可视化平台.你可以使用 Kibana 来搜索,查看存储在 Elasticsearch 索引中的数据并与之交互.你可 ...