• 最下生成树原理


    转自 http://www.slyar.com/blog/kruskal-disjoint-sets-c.html  

    Kruskal比较适用于稀疏图,是一种贪心算法:为使生成树上边的权值和最小,则应使生成树中每一条边的权值尽可能地小。

    具体做法:找出森林中连接任意两棵树的所有边中,具有最小权值的边,如果将它加入生成树中不产生回路,则它就是生成树中的一条边。这里的关键就是如何判断"将它加入生成树中不产生回路"。

    《算法导论》提供的一种方法是采用一种"不相交集合数据结构",也就是并查集了。具体的实现看代码好了,反正核心内容就是如果某两个节点属于同一棵树(Find_Set),那么将它们合并(Union)后一定会形成回路

    编写程序:对于如下一个带权无向图,给出所有边以及权值,用kruskal算法求最小生成树。

    kruskal

    输入数据:

    11
    A B 7
    A D 5
    B C 8
    B D 9
    B E 7
    C E 5
    D E 15
    D F 6
    E F 8
    E G 9
    F G 11

    输出:

    A - D : 5
    C - E : 5
    D - F : 6
    A - B : 7
    B - E : 7
    E - G : 9
    Total:39

    代码如下,其实代码可以优化的地方很多,例如当生成树的边数已经等于n-1时即可停止循环...因为不是ACM题,故优化省略不写,只当做算法学习...

    维基百科上介绍:

    步骤

    1. 新建图G,G中拥有原图中相同的节点,但没有边
    2. 将原图中所有的边按权值从小到大排序
    3. 从权值最小的边开始,如果这条边连接的两个节点于图G中不在同一个连通分量中,则添加这条边到图G中
    4. 重复3,直至图G中所有的节点都在同一个连通分量中

    [编辑]证明

    1. 这样的步骤保证了选取的每条边都是桥,因此图G构成一个树。
    2. 为什么这一定是最小生成树呢?关键还是步骤3中对边的选取。算法中总共选取了n-1条边,每条边在选取的当时,都是连接两个不同的连通分量的权值最小的边
    3. 要证明这条边一定属于最小生成树,可以用反证法:如果这条边不在最小生成树中,它连接的两个连通分量最终还是要连起来的,通过其他的连法,那么另一种连法与这条边一定构成了环,而环中一定有一条权值大于这条边的边,用这条边将其替换掉,图仍旧保持连通,但总权值减小了。也就是说,如果不选取这条边,最后构成的生成树的总权值一定不会是最小的。

     

    [编辑]性质(MST性质)

    1.若图是连通的无向图或强连通的有向图,则从图中任意一个顶点出发调用一次bfs或dfs后,便可以系统地访问图中所有顶点;若图是有根的有向图,则从根出发通过调用一次dfs或bfs,亦可系统地访问所有顶点。在这种情况下,图中所有顶点加上遍历过程中经过的边所构成的子图,称为原图的生成树。
    2.对于不连通的无向图和不是强连通的有向图,若有根或者从根外的任意顶点出发,调用一次bfs或dfs后,一般不能系统地访问所有顶点,而只能得到以出发点为根的连通分支(或强连通分支)的生成树。要访问其它顶点,还需要从没有访问过的顶点中找一个顶点作为起始点,再次调用bfs或dfs,这样得到的是生成森林。

    由此可以看出,一个图的生成树是不唯一的,不同的搜索方法可以得到不同的生成树,即使是同一种搜索方法,出发点不同亦可导致不同的生成树。

    可以证明:具有n个顶点的带权连通图,其对应的生成树有n-1条边。

    [编辑]时间复杂度

    O(Elog2E)

    [编辑]算法

    KRUSKAL-FUNCTION(G, w)
    1    F := 空集合
    2    for each 圖 G 中的頂點 v
    3        do 將 v 加入森林 F
    4    所有的邊(u, v) ∈ E依權重 w 遞增排序
    5    for each 邊(u, v) ∈ E
    6        do if u 和 v 不在同一棵子樹
    7            then F := F ∪ {(u, v)}
    8                將 u 和 v 所在的子樹合併

     

  • 相关阅读:
    web移动端开发经验总结
    《前端JavaScript面试技巧》笔记一
    《SEO在网页制作中的应用》视频笔记
    web前端开发笔记(2)
    OAuth2.0理解和用法
    基于hdfs文件创建hive表
    kafka 配置事项
    centos7时间同步
    lambda架构
    hbase hadoop版本
  • 原文地址:https://www.cnblogs.com/xiangshancuizhu/p/2429003.html
Copyright © 2020-2023  润新知