最小生成树学习

概述:

在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即),而 w(u, v) 代表此边的权重,若存在 T 为 E 的子集(即)且为无循环图,使得 w(T)
最小,则此 T 为 G 的最小生成树。

     最小生成树其实是最小权重生成树的简称。

最小生成树:

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

应用:

网络G表示n个城市之间的通信线路网线路(其中顶点表示城市,边表示两个城市之间的通信线路,边上的权值表示线路的长度或造价)。可通过求该网络的最小生成树达到求解通信线路或总代价最小的最佳方案。

如何求最小生成树呢?

一是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):通过割的所有边中权值最小的边(可能有多条)。

最小生成树生成的伪代码:

GENERIC-MST(G, w)
    A=空集
    while A does not form a spanning tree(如果A不能构成一个生成树)
        do find an edge(u,v) that is safe for A(找A的安全边)
            A=AU{(u,v)}
    return A

算法导论定理:

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来说是安全的。

伪代码实现:

Kruskal 算法

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

(FIND-SET(u)是找出u所在的连通分支。Kruskal在全局中找权值最小的边,然后判断此边是否“合法”,进行取舍,直到遍历完所有的边。Kruskal算法的运行时间为O(ElgV)。)

Prim算法(Prim适用于稠密图,对于给定坐标求最小生成树的题目再合适不过。)

MST-PRIM(G, w, r)
    for each u∈V[G]
        do key[u]=∞
          π(u) = NIL     // π(u)是u的前趋
    key[r] = 0
    Q=V[G]
    while Q != 空集
        do u=EXTRACT-MIN(Q)
            for each v∈Adj[u]
                do if v∈Q and w(u,v)<key[v]
                    then π(v)=u
                          key[v] = w(u,v)       // 更新key[v]</span></span>

(Q是一个优先队列,key[v]是所有将v与树中某一顶点相连的边中的最小权值,若不存在这样的边,则k[v]=∞。Prim算法在局部寻找权值小的的边(此边必合法),直到遍历完所有的节点。Prim算法的运行时间为O(ElgV),与Kruskal算法渐近相等。Prim算法实际上使用了与Dijkstra算法同样的策略,维护了一个权值数组key,在迭代过程中不断的更新。)

-------------------------------------------------------

代码:

以后加。。。。。。。。。。。。。。。。

----------------------------------------------------------------------------------------------

来源:点击打开链接

最小生成树学习

时间: 2024-11-07 15:21:49

最小生成树学习的相关文章

最小生成树学习总结

dijkstra算法 floyd算法 最小生成树 将所有的分成两个集合,一个是已经按照最小值排完顺序的,另外一个是没有排完顺序的,每次在查找从排完顺序的集合到未排完顺序的集合的最短路径,然后将未排完顺序的集合里面的值加入到已排完顺序的集合里. 最小生成树算法: 例题,第一行输入N和M,代表点的个数和他们之间存在的连线条数: 下面N行每行有三个整数a,b,L,代表a和b 之间的权值(或长度)为L; 输出: 输出这些点连成一个联通块,所用连线的权值和的最小值: input:5 71 2 101 3

最小生成树学习笔记

最小生成树学习笔记 https://zh.wikipedia.org/wiki/%E6%9C%80%E5%B0%8F%E7%94%9F%E6%88%90%E6%A0%91 https://zh.wikipedia.org/wiki/%E6%99%AE%E6%9E%97%E5%A7%86%E7%AE%97%E6%B3%95 注意时间复杂度 模板TBD 原文地址:https://www.cnblogs.com/wuyuanyuan/p/8467905.html

数据结构学习笔记(十)-图的最小生成树与拓扑排序

一.最小生成树 首先应该理解最小生成树的定义: 包含图的所有顶点,V-1条边 没有回路 边的权重和最小 那么实际问题中用到最小生成树是什么时候呢?很多人都觉得学习算法没用,在实际生活工作中根本就用不上,其实并不是用不上,只是你根本没有想到要去用而已!使用了算法后你就会发现事情原来可以这么简单高效! 实际中如需要使用最少的电线给一栋房子安装电路.就可以用最小生成树解决. 1. Prim算法 该算法利用了贪心的思想,大体上与dijkstra算法类似,都需要对每一个顶点保存一个距离值dv和pv,以及一

学习日志---图之最小生成树算法

最小生成树: 从最小生成树的定义可知,构造有n个结点的无向连通带权图的最小生成树,必须满足以下三条: (1)构造的最小生成树必须包括n个结点: (2)构造的最小生成树中有且只有n-1条边: (3)构造的最小生成树中不存在回路. 构造最小生成树的方法有许多种,典型的构造方法有两种,一种称作普里姆(Prim)算法,另一种称作克鲁斯卡尔(Kruskal)算法. 特里姆算法 假设G=(V,E)为一个带权图,其中V为带权图中结点的集合,E为带权图中边的权值集合.设置两个新的集合U和T,其中U用于存放带权图

学习笔记:最小生成树算法

一.普里姆(Prim)算法 ①初始化新图仅包含原图中的任意一个顶点,不包含任何边. ②从原图中选择一条权值最小的边,该边满足有且仅有一个顶点在新图中.将该边加入新图. ③重复直至所有顶点都在新图中,新图即最小生成树. 二.克鲁斯卡尔(Kruskal)算法 ①初始化新图包含原图中的所有顶点,不包含任何边. ②从小到大遍历原图中所有边,若边中的两个顶点在新图中不存在连通路径,则将其加入新图. ③遍历结束后,新图即最小生成树. 三.实现 import java.util.TreeMap; import

[学习-思考-探究]莫队算法 曼哈顿最小生成树与分块区间询问算法-4

若要转载,不需要联系我,只需要在下面回复一下并注明原文. 在线区间询问算法(奇妙算法) 这是最神奇的算法,不仅简单还可以实现在线询问+修改. 考虑基础算法中的优化. 如果我们把整个区间分成$n^{\frac{1}{3}}$块,那么就可以记录任意两块之间的状态啦! 然后只要套用基础算法当中的操作就可以啦! 总空间复杂度和时间复杂度都是$O(n^{\frac{3}{4}})$,还是相当好的. 下面是例题: https://loj.ac/problem/6219 小Y的房间 标程就不放出来啦. 如有不

算法学习三阶段

?? 第一阶段:练经典经常使用算法,以下的每一个算法给我打上十到二十遍,同一时候自己精简代码, 由于太经常使用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都能够把程序打 出来. 1.最短路(Floyd.Dijstra,BellmanFord) 2.最小生成树(先写个prim,kruscal 要用并查集,不好写) 3.大数(高精度)加减乘除 4.二分查找. (代码可在五行以内) 5.叉乘.判线段相交.然后写个凸包. 6.BFS.DFS,同一时候熟练hash 表(要熟,要灵活,代码要

外出学习有感

五一假期外出学习总结 五一放假了,哎,高兴个大头鬼啊! 哪来的什么假期,走,外出培训! 当然,外出培训的虽是占用了我们的假期时间,但是我们还是十分激动的,因为在外学习的我们收获了很多. 第一天,上午讲了树基础和图的存储,都是非常基础的东西,所以就当是复习了一下,学起来也比较轻松,但是图的存储也有一些东西没有理解,就比如prufer数列,感觉听得晕晕呼呼的,下午考试,我考了60分,额,当然会的额没有,该会的都不会,不该会的也都不会! 第二天,上午讲到最近公共祖先,开始讲用倍增和书剖求LCA的时候听

学习进度表

周数 专业学习目标 专业学习时间 新增代码量 博客发表量 人文方面的学习 知识技能总结 13 使用WWW服务搭建信息浏览网站,使用FTP服务实现文件的上传下载. 学习最小生成树.Prim算法.Kruskal算法.Dijkstra算法. 用Javascript脚本语言实现状态栏信息的显示,把长数字进行转换,使之分位显示. 4 275 1 参加了“软件学院团委学生会干部换届竞选大会”.在此过程中听了演讲,学习到了演讲的秘诀,以及如何和大家进行更好的沟通.如何提高人际交往的能力,如何做好一名合格的学生