有向图生成树是如何画的_漫画:什么是最小生成树?

ffa57065d9f702d5230000a1e6ae9b97.png

作者 | 小灰

来源 | 程序员小灰

53c6cfee04bc1ad3613102b30618472b.pngad8d6d30edfae51e529cf6cb07735db5.png

————— 第二天 —————

0c4ccd34905323a33cb4edc157aed500.pngf4aa323166229a2aa8ec7714c8909988.pngc4f138a2b547a0d9548c1680138bf38b.png2d29323c763f32184263ffec9a555d06.png518df35385d2d4c83a68945d4f4f750a.png785a0ede3442d5b1e41b2c24b10c8ed6.png2ea343dcfafb88fd26e404de577e3502.png

————————————

03a86fad563b0996f9c908278a248bf4.png0899f45b95034eb374d7f5ec682b5814.png48c8159c2d5ce731f82128e63557ad9a.png8396e2b04698141713e5dc50d4a1a881.png579302736ad9acfa032060d0c44ac838.png833574506ffdfdc32c597b983f03b186.png

首先看看第一个例子,有下面这样一个带权图:

f2d97b55edac7c8801a48c4cf1800698.png

它的最小生成树是什么样子呢?下图绿色加粗的边可以把所有顶点连接起来,又保证了边的权值之和最小:

81cc6676192217520e797d51d31b2c25.png

去掉那些多余的边,该图的最小生成树如下:

932177cd6181d9e57a43ca4557764f56.png

下面我们再来看一个更加复杂的带权图:

bb4ec47f4f62dcafa1dd5d1d3ac3f5d3.png

同样道理,下图绿色加粗的边可以把所有顶点连接起来,又保证了边的权值之和最小:

e207383be5e65dfaed928a202f4833e8.png

去掉那些多余的边,该图的最小生成树如下:

beea55870a70b8b19d47e0da1a9c547e.pngf5c898e571633ea68e992a959411dcca.png6f91a710abdafd5818df659e78546591.pngea3e120f00a71e2327ed093547ebf4fc.png

怎样铺设才能保证成本最低呢?

城市之间的交通网就像一个连通图,我们并不需要在每两个城市之间都直接进行连接,只需要一个最小生成树,保证所有的城市都有铁路可以触达即可。

8124a098eb920053ab7e5ccbc4a3942e.png336e0b26daefbc4fd93a3129ebd0f2a8.png3dd155a82f1c70a71a9a1adc990a8856.png

Prim算法是如何工作的呢?

这个算法是以图的顶点为基础,从一个初始顶点开始,寻找触达其他顶点权值最小的边,并把该顶点加入到已触达顶点的集合中。当全部顶点都加入到集合时,算法的工作就完成了。Prim算法的本质,是基于贪心算法

接下来说一说最小生成树的存储方式。我们最常见的树的存储方式,是链式存储,每一个节点包含若干孩子节点的指针,每一个孩子节点又包含更多孩子节点的指针:

这样的存储结构很清晰,但是也相对麻烦。为了便于操作,我们的最小生成树用一维数组来表达,数组下标所对应的元素,代表该顶点在最小生成树当中的父亲节点。(根节点没有父亲节点,所以元素值是-1)

aeb5b0bd41e76f9e316d54f868a30deb.png

下面让我们来看一看算法的详细过程:

1.选择初始顶点,加入到已触达顶点集合。

b510accd6865fcffe5588e65893ca1ac.png

2.从已触达顶点出发,寻找到达新顶点的权值最小的边。显然从0到2的边权值最小,把顶点2加入到已触达顶点集合,Parents当中,下标2对应的父节点是0。

945203ca5d1122d5402de15be118e03d.png

3.从已触达顶点出发,寻找到达新顶点的权值最小的边。显然从2到4的边权值最小,把顶点4加入到已触达顶点集合,Parents当中,下标4对应的父节点是2。

06a388e8ffa2a0055b2a9cb660310924.png

4.从已触达顶点出发,寻找到达新顶点的权值最小的边。显然从0到1的边权值最小,把顶点1加入到已触达顶点集合,Parents当中,下标1对应的父节点是0。

7e1527cf7d4ac2303f07a0e54ad768cb.png

5.从已触达顶点出发,寻找到达新顶点的权值最小的边。显然从1到3的边权值最小,把顶点3加入到已触达顶点集合,Parents当中,下标3对应的父节点是1。

76e73ec15aa0c2ffc92764e3f67f58ed.png

这样一来,所有顶点都加入到了已触达顶点集合,而最小生成树就存储在Parents数组当中。

f26b6afdc5f3f8bff251fd7c787a8dda.pngaab14446777cb6018f83338d7b18638f.png

final static int INF = Integer.MAX_VALUE;

public static int prim(int[][] matrix){

List reachedVertexList = new ArrayList;

//选择顶点0为初始顶点,放入已触达顶点集合中

reachedVertexList.add(0);

//创建最小生成树数组,首元素设为-1

int parents = new int[matrix.length];

parents[0] = -1;

//边的权重

int weight;

//源顶点下标

int fromIndex = 0;

//目标顶点下标

int toIndex = 0;

while (reachedVertexList.size < matrix.length) {

weight = INF;

//在已触达的顶点中,寻找到达新顶点的最短边

for (Integer vertexIndex : reachedVertexList) {

for (int i = 0; i < matrix.length; i++) {

if (!reachedVertexList.contains(i)) {

if (matrix[vertexIndex][i] < weight) {

fromIndex = vertexIndex;

toIndex = i;

weight = matrix[vertexIndex][i];

}

}

}

}

//确定了权值最小的目标顶点,放入已触达顶点集合

reachedVertexList.add(toIndex);

//放入最小生成树的数组

parents[toIndex] = fromIndex;

}

return parents;

}

public static void main(String[] args) {

int matrix = new int{

{0, 4, 3, INF, INF},

{4, 0, 8, 7, INF},

{3, 8, 0, INF, 1},

{INF, 7, INF, 0, 9},

{INF, INF, 1, 9, 0},

};

int parents = prim(matrix);

System.out.println(Arrays.toString(parents));

}

这段代码当中,图的存储方式是邻接矩阵,在main函数中作为测试用例的图和对应的邻接矩阵如下:

c809124bd09b64da66801a2aac9ffe62.png

当然,也可以使用邻接表来实现prim算法,有兴趣的小伙伴可以尝试写一下代码。

7c53537923fe40304ed671d33c5b8ae5.pngffcb5d98099084d4aac0b7423f4f0b6d.png0ccf9124e7d6bfa962602ab828bba2ca.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/500951.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

printf 指针地址_c语言对指针的理解

先来讲一下本人学指针的经历&#xff1a;大一的时候刚接触c语言对指针这东西真的是太迷了&#xff0c;感觉麻烦难懂不想其他语言一样。但是搞懂以后就被指针的魅力吸引甚至喜欢上c语言。不多讲&#xff0c;开始&#xff01;(文章可能有些长&#xff0c;但放心全是基础的东西&am…

python 时分秒毫秒_python将时分秒转换成秒的实例

处理数据的时候遇到一个问题&#xff0c;从数据库里导出的数据是时分秒的格式&#xff1a;hh:mm:ss &#xff0c;现在我需要把它转换成秒&#xff0c;方便计算。原数据可能分两种情况&#xff0c;字段有可能是文本字符串类型的&#xff0c;也有可能是时间类型&#xff0c;他们的…

信息系统项目管理师论文优秀范文_软考 信息系统项目管理师备考指南

1&#xff0e;考试简介信息系统项目管理师考试作为全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff08;一般简称为“软考”&#xff09;的一个高级级别&#xff0c;是从2005年开始的&#xff0c;一共考了2次&#xff0c;即2005年5月&#xff0c;200…

单片机led闪烁代码_单片机驱动LED发光二极管的电路以及编程

一、单片机驱动单个发光二极管1.电路代码:1.点亮单个LED二极管#include《reg51.h> sbit LED1P1^0&#xff1b;void main(void){LED11&#xff1b;while(1)&#xff1b;{LED10} }2.单个LED数码管以固定频率闪烁#include<reg51.h> sbit LED1P1^0;void Delay(unsigned in…

macos系统自动安装mysql_macos系统安装mysql

MacOS系统安装mysql一、下载官网下载链接地址&#xff1a;https://dev.mysql.com/downloads/mysql/二、安装打开文件是pkg包&#xff0c;双击进行安装&#xff1a;按照提示&#xff1a;点击最下面的MySQL控制按钮&#xff0c;启动数据库运行&#xff1a;在此可以启动和停止MySQ…

水晶报表中对某一栏位值进行处理_合并报表——非同一控制下的企业合并amp;同一控制下的企业合并...

【写在前面】长期股权投资企业的一种投资行为&#xff0c;投资方通过该行为享有被投资单位的股利分配、净利润等投资收益&#xff0c;处理的是母公司&#xff08;投资方&#xff09;的个别财务报表。只有控股合并才需要编制合并报表&#xff0c;意味着后续计量采用的是成本法。…

python测试框架untest怎么循环执行_unittest如何在循环遍历一条用例时生成多个测试结果...

引用自:http://blog.csdn.net/kaku21/article/details/42124593参考网址&#xff1a;http://programmaticallyspeaking.com/test-data-provider-using-python-metaclass.html使用TestNG进行测试的时候&#xff0c;允许使用外部数据源来驱动测试方法的执行&#xff0c;举个例子&…

python杨辉三角_yiduobo的每日leetcode 118.杨辉三角 amp;amp; 119.杨辉三角II

祖传的手艺不想丢了&#xff0c;所以按顺序写一个leetcode的题解。计划每日两题&#xff0c;争取不卡题吧。118.杨辉三角https://leetcode-cn.com/problems/pascals-triangle/119.杨辉三角IIhttps://leetcode-cn.com/problems/pascals-triangle-ii/经典的数学题。118题需要求出…

为什么链接不上mysql数据库_java链接不上数据库,怎么解决!

居正w去年刚好做过这个&#xff0c;给你贴下我的链接代码try { Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); //加载sqlserver JDBC驱动程序 //Class.forName("org.gjt.mm.mysql.Driver"); System.out.pr…

世界上最难的视觉图_世界上最长的蛇有多长?四川惊现55米洪荒巨蟒(图)

蛇&#xff0c;一直是站在食物链顶端的致命生物&#xff0c;蟒蛇更是能够吞食人类的恐怖巨兽。网传世界上最长的蛇有500米之长&#xff0c;名为“红海巨蛇”&#xff0c;已被证实为虚假传言&#xff0c;以地球现在的环境是不可能出现如此之大的蛇的。据说四川发现了罕见的55米长…

解析器 java_java 常用的解析工具

这里介绍两种 java 解析工具。第一种&#xff1a;java 解析 html 工具 jsoup第二种&#xff1a; java 解析 XML 工具 Dom4jjsoupjsoup是一个用于处理真实HTML的Java库。它提供了一个非常方便的API&#xff0c;用于提取和操作数据&#xff0c;使用最好的DOM&#xff0c;CSS和类似…

php 比java 快_php比java要快在哪里

php比java要快在哪里一些Java可以做的事情php做不了或者说要借助另外的工具才可以做&#xff0c;要但就开发网站这个事情来说&#xff0c;php确实是要比Java效率高&#xff0c;尤其是相对简单的项目。首先&#xff0c;Java的架构要比Php复杂&#xff0c;先不说各种开发框架&…

斯皮尔曼相关系数_惊艳!JASP相关系数矩阵及热力图

今天起我们新增一个案例数据&#xff0c;犯罪数据。这是mei国50个州关于犯罪率的一组数据&#xff0c;包括人口、面积、收入、文盲率、高中毕业率、霜冻天数、犯罪率共7个指标&#xff0c;现在我们想考察一下州犯罪率和其他因素间的关系。数据视图如下&#xff1a;数据取自《R语…

邻接矩阵和邻接表_[力扣743] 带权邻接表的单源最短路

题目链接743. 网络延迟时间 题目描述有 N 个网络节点&#xff0c;标记为 1 到 N。给定一个列表 times&#xff0c;表示信号经过有向边的传递时间。 times[i] (u, v, w)&#xff0c;其中 u 是源节点&#xff0c;v 是目标节点&#xff0c; w 是一个信号从源节点传递到目标节点的…

opencv java ubuntu_Ubuntu 16.04配置OpenCV 3.1.0 for Java

我们都知道&#xff0c;OpenCV是基于C的开源计算机视觉库&#xff0c;但是从2.4.4版本开始提供了Java绑定&#xff0c;也就是说&#xff0c;我们也可以使用Java来开发基于OpenCV的计算机视觉应用。目前&#xff0c;最新的版本是3.1.0&#xff0c;在本文中将会介绍如何中Ubuntu …

service 层 拼接的html 代码如何直接返回_字符串拼接,会走StringBuilder 吗?

前言最近在突然想到了String字符串拼接问题&#xff0c;于是做了一个demo测试了一下&#xff0c;到底String类型的字符串在拼接的时候&#xff0c;哪种情况下会走会走StringBulider进行字符串拼接&#xff0c;而哪种情况编译器会对代码进行优化&#xff1f;话不多说&#xff0c…

迁移学习训练集准确率一直上不去_可以提高你的图像识别模型准确率的7个技巧...

假定&#xff0c;你已经收集了一个数据集&#xff0c;建立了一个神经网络&#xff0c;并训练了您的模型。但是&#xff0c;尽管你投入了数小时(有时是数天)的工作来创建这个模型&#xff0c;它还是能得到50-70%的准确率。这肯定不是你所期望的。下面是一些提高模型性能指标的策…

华为云客户端_华为公布云手机计费清单,要不要光刻机也给出了答案

华为云手机一出来&#xff0c;大家的好奇心就上来了。这就是解决华为无芯片的代替方案。纷纷说道&#xff0c;可以绕开光刻机&#xff0c;光刻机瞬间变废铁。当时我还发布过文章分析&#xff1a;现在的云手机只是一个云端应用&#xff0c;并不是真正的云手机。需要在手机或电脑…

java 柱状图 宽度_Java实现 LeetCode 84 柱状图中最大得矩形

84. 柱状图中最大的矩形给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。以上是柱状图的示例&#xff0c;其中每个柱子的宽度为 1&#xff0c;给定的高度为…

java中为什么要用注解_java中的注解,真的很重要,你理解了嘛?

这篇文章开始讲解java中的注解&#xff0c;在平时的开发当中我相信你或多或少的接触过注解。比如你可能都见过override&#xff0c;它代表的就是一个注解。但是&#xff0c;为了更加清晰的去介绍注解&#xff0c;我还是先给出一个例子&#xff0c;让你能够方便的理解。一、认识…