最小生成树,Prim算法与Kruskal算法,408方向,思路与实现分析

最小生成树,老生常谈了,生活中也总会有各种各样的问题,在这里,我来带你一起分析一下这个算法的思路与实现的方式吧~~

在考研中呢,最小生成树虽然是只考我们分析,理解就行,但我们还是要知道底层是怎么实现的,话不多说,进入正题~~

什么是生成树?什么是最小生成树

总所周知,对于一个无向连通图,我们想把他看成一个树的话,那么就不能太乱,也就引出了,如果对于一个生成树(不唯一,满足条件即可),如果砍去它的一条边,则会变成非连通图,如果加上一条边则会形成一个回路,也就是包含图的全部顶点的一个极小连通子图,如下所示~~

因此,对于顶点数为n的图,生成树应含有n-1条边~~

那么,最小生成树又是什么呢?

当边带权时,我们想要一个生成树,使得带权路径和最小,那么这样的生成树就被我们称作最小生成树(不唯一),也就是边的权值之和最小的生成树(MST,Minimum-Spanning-Tree)~~

那么怎么求一个最小生成树呢?

没错,我们相求一个最小生成树,我们的前辈大牛也想过这个问题,也就引出了两个算法,一个是Prim算法(普里姆),和Kruskal算法(克鲁斯卡尔)~~

先给一个案例我们来分析一下,经典的修路~~

我们想要使得我们这个小镇全都连通,但又花费经济最少(虚线边数值代表所需金钱,也就是权值),该怎么修呢?先给出答案,接下来我们用两个算法分别分析一下思路以及底层实现~~

Prim算法(普里姆)思路分析与底层实现

Prim算法:从选取的某一个顶点开始,每次将代价最小的新顶点纳入生成树,直到所有顶点都纳入为止~~

思路分析:也就是并查集内加新顶点,为了方便理解,我们把并查集每次都纳入的顶点看成一个在一个圈里加入新顶点,不属于圈里的即为连通的顶点,如图所示算法思路~~

底层实现:我们这里定义两个数组一个为isJoin[]和lowCost[]数组,isJoin[]用来标记是否已加入树,lowCost[]用来表示各节点加入当前树时的最低代价~~

如第一个步骤的时候,只有c点加入了树,那么我们就当c点已经加入了树,也就是说isJoin[6]变为了如表所示(为了方便我们把数组下标换成我们的字母abcdef)~~

C A B D E F
isJoin[6] 1 0 0 0 0 0

此时我们的lowCost[6]对应就应为(没有边直接连通则为无穷):

C A B D E F
lowCost[6] 0 1 5 4 6 4

lowCost最小为1,也就是C与A连接所需代价最小,所以当第1步结束时,我们将A连入树中,修改对应isJoin[6]和lowCost[6]~~

C A B D E F
isJoin[6] 1 1 0 0 0 0
C A B D E F
lowCost[6] 0 0 5 4 6 4

权:1~~

lowCost最小为4,也就是(D或者F)与圈AC连接所需代价最小,所以当第2步结束时,我们将F连入树中,修改对应isJoin[6]和lowCost[6]~~

C A B D E F
isJoin[6] 1 1 0 0 0 1
C A B D E F
lowCost[6] 0 0 5 2 6 0

权:1+4~~

因为现在要和圈ACF连接,D如果想代价最小就可以选择DF连接(2),而不是以前的DC连接(4),2代价更小,这就是lowCost[]用来表示各节点加入当前树时的最低代价的意思~~

重复此过程~~

C A B D E F
isJoin[6] 1 1 0 1 0 1
C A B D E F
lowCost[6] 0 0 5 0 6 0

权:1+4+2~~

接下来

C A B D E F
isJoin[6] 1 1 1 1 0 1
C A B D E F
lowCost[6] 0 0 0 0 3 0

权:1+4+2+5~~

最后

C A B D E F
isJoin[6] 1 1 1 1 1 1
C A B D E F
lowCost[6] 0 0 0 0 0 0

权:1+4+2+5+3=15~~

Kruskal算法(克鲁斯卡尔)思路分析与底层实现

双生关系,Prim是每次选一个连到树里代价最小的顶点构成一个树,Kruskal是每次选一条权值最小的边,使这条边两端连通(如果原本就已经连通就不选),直到所有结点都连通~~

思路分析:上图~~

底层实现:并查集~~

按权值排序~~

weight 1 2
1 A C
2 D F
3 B E
4 D C
4 C F
5 A D
5 B C
6 A B
6 C E
6 E F

依次往下看,1和2两个点是否属于同一集合(先规定所有顶点都属于不同的集合,如果两个顶点相连,则这两个顶点构成了一个集合)~~

如第一次,weight为1,A和C为不同集合,相连,通过~~(集合AC,B,D,E,F)

第二次,weight为2,D和F为不同集合,相连,通过~~(集合AC,DF,B,E)

第三次,weight为3,B和E为不同集合,相连,通过~~(集合AC,DF,BE)

第四次,weight为4,D和C虽然DF是一个集合,AC是一个集合,但DF和AC不是一个集合里的不连通,所以相连,通过~~(集合ACDF,BE)

第五次,weight为4,C和F同属于ACDF集合里,所以不相连,不通过~~(集合ACDF,BE)

第六次,weight为5,A和D同属于ACDF集合里,所以不相连,不通过~~(集合ACDF,BE)

第七次,weight为5,B和C不属于同一个集合里,所以相连,通过~~(集合ABCDEF)

至此成功~~

最小生成树还是简单的,为我们后面学习最短路径做基础,这里大家好好看看,下周我就来谈一谈最短路径的几个算法,这两者很像,但要区分开来~~

最小生成树,Prim算法与Kruskal算法,408方向,思路与实现分析的更多相关文章

  1. 转载:最小生成树-Prim算法和Kruskal算法

    本文摘自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html 最小生成树-Prim算法和Kruskal算法 Prim算 ...

  2. 最小生成树Prim算法和Kruskal算法

    Prim算法(使用visited数组实现) Prim算法求最小生成树的时候和边数无关,和顶点树有关,所以适合求解稠密网的最小生成树. Prim算法的步骤包括: 1. 将一个图分为两部分,一部分归为点集 ...

  3. 最短路径问题,BFS,408方向,思路与实现分析

    最短路径问题,BFS,408方向,思路与实现分析 继上回挖下的坑,不知道大家有没有认真看最小生成树呢?很简单,这回也讲讲正常难度的,看不懂就来这里看看,讲的很好~~ 最短路径问题 说起这个问题,先说个 ...

  4. 最小生成树---Prim算法和Kruskal算法

    Prim算法 1.概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (gra ...

  5. 最小生成树——Prim算法和Kruskal算法

    洛谷P3366 最小生成树板子题 这篇博客介绍两个算法:Prim算法和Kruskal算法,两个算法各有优劣 一般来说当图比较稀疏的时候,Kruskal算法比较快 而当图很密集,Prim算法就大显身手了 ...

  6. 最小生成树Prim算法和Kruskal算法(转)

    (转自这位大佬的博客 http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html ) Prim算法 1.概览 普里姆算法(Pr ...

  7. hdu1233 最小生成树Prim算法和Kruskal算法

    Prim算法 时间复杂度:O(\(N^2\),N为结点数) 说明:先任意找一个点标记,然后每次找一条最短的两端分别为标记和未标记的边加进来,再把未标记的点标记上.即每次加入一条合法的最短的边,每次扩展 ...

  8. 数据结构与算法系列----最小生成树(Prim算法&Kruskal算法)

     一:Prim算法       1.概览 普里姆算法(Prim算法).图论中的一种算法.可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中.不但包含了连通图里的全部顶点(英语:Ve ...

  9. 最小生成树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind

    最小支撑树树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind 最小支撑树树 前几节中介绍的算法都是针对无权图的,本节将介绍带权图的最小 ...

随机推荐

  1. Pytorch系列:(一)常用基础操作

    各种张量初始化 创建特殊类型的tensor a = torch.FloatTensor(2,3) a = torch.DoubleTensor(2,3) ... 设置pytorch中tensor的默认 ...

  2. Webpack的理解以及解决了的问题

    一.背景 Webpack 最初的目标是实现前端项目的模块化,旨在更高效地管理和维护项目中的每一个资源 模块化 最早的时候,我们会通过文件划分的形式实现模块化,也就是将每个功能及其相关状态数据各自单独放 ...

  3. C++雾中风景17:模板的非推断语境与std::type_identity

    乍一看这个标题很玄乎,但是其实这只是涉及一个很简单的CPP的模板推导的知识点. 笔者近期进行CPP开发工作时,在编译时遇到了如下的模板类型的推断错误:note: candidate template ...

  4. B - 抽屉 POJ - 2356 (容斥原理)

    The input contains N natural (i.e. positive integer) numbers ( N <= 10000 ). Each of that numbers ...

  5. 03 Django web服务开发 - URL路由

    Django中的APP -Django中的一个APP就是一个应用的意思 -项目可以包含多个APP(多个应用) -一个项目对应一个网站(生活服务网站) 一个APP队形网站的一个应用(二手交易,家政服务) ...

  6. Linux 服务管理的两种方式service和systemctl

    service命令 service命令其实是去/etc/init.d目录下,去执行相关程序 ``` # service命令启动redis脚本 service redis start # 直接启动red ...

  7. 动态地绑定到它的 is 特性,可以实现动态组件

    前面的话 让多个组件使用同一个挂载点,并动态切换,这就是动态组件.本文将详细介绍Vue动态组件 概述 通过使用保留的 <component> 元素,动态地绑定到它的 is 特性,可以实现动 ...

  8. 看了这篇还不会Linux性能分析和优化,你来打我

    前言 一般互联网的项目都是部署在linux服务器上的,如果linux服务器出了问题,那么咱们平时学习的高并发,稳定性之类的是没有任何意义的,所以对linux性能的把握就显得非常重要,当然很多同学可能觉 ...

  9. DVWA之File Upload (文件上传漏洞)

    目录 Low: Medium: 方法一:抓包修改文件的type 方法二:00截断 High: Impossible : Low: 源代码: <?php if( isset( $_POST[ 'U ...

  10. WindowsPE 第五章 导出表

    导出表 PE中的导出表存在于动态链接库文件里.导出表的主要作用是将PE中存在的函数导出到外部,以便其他人可以使用这些函数,实现代码重用. 5.1导出表的作用 代码重用机制提供了重用代码的动态链接库,它 ...