(原创)最小生成树之Prim(普里姆)算法+代码详解,最懂你的讲解
Prim算法
(哈欠)在创建最小生成树之前,让我们回忆一下什么是最小生成树。最小生成树即在一个待权值的图(即网结构)中用一个七拐八绕的折线串连起所有的点,最小嘛,顾名思义,要权值相加起来最小,你当然可以拿起笔来就算你脑中的每一种可能,但是如果你了解了这种算法,你就能跟我一样,一次画出完美答案。
上个栗子:

我先说一哈这个算法的方法论,然后我们来代码实现一下,在讲解开始之前,敲黑板,记得我们要生成一个权值最小的树,所以每一步都要考虑到树的每一个结点,不要孤立地用一个结点来对比从而走上死路,我们任选一个点开始生成,教材里选的 v0,那我们就选 v8,战斗开始
v8 有三条路,分别通往v1 v2 v3,v2那条路权值最小,ok, v2→v8,然后我们该看什么,如果你说找和 v2 相邻的 v8 以外的边,那我刚才的强调就gg了,我们找v2 和 v8除相连的线之外的所有分支,易得 v8→v1的权值最小,ok,下一步找哪几个点?v2 v1 v8这三个点除两条连接线以外的所有分支,挑最小的那一条,后面重复前面的操作,每次都把新加入的伙伴算在找线之内才对,自己画一下给答案:

操作一遍是不是发现还真的跟哪个点开始没鸡儿关系,因为每个点都要连到,关键就在于沿最小分支找点的时候一定要把它看成一个树结构来找,才算是最小生成树。
还是给一下标准定义:
我们把构造连通网的最小代价(权值)生成树 称为最小生成树 (Minimum Cost Spanning Tree)。
方法论就到这里,相信下一次看到同样的现实问题,你也应该能在第一时间用正确的思路找到合适的路。
在代码实现之前,我们先请来连通图的好基友——邻接矩阵

我们发现一行一行的矩阵很容易显示权值,这样就可以快速对比权值的大小,只要在循环的每一步留存下权值较小的边权值和顶点下标,就可以实现。
和以前一样,我们还是用 INFINITY 来表示无限大,即不存在该边
代码如下:
void MiniSpanTree_Prim(MGragh G)
{
int mini,i,j,k;
int adjvex[MAXVEX]; //保存相关顶点下标
int lowcost[MAXVEX]; //保存相关顶点间边的权值
lowcost[] = ;//这里把第0位的权值置0表示v0已加入生成树
//ps:lowcost[i] = 0 表示i那个下标的顶点加入生成树
adjvex[] = ; //初始化第一个顶点的下标为0
for(i = ; i < G.numVertexes; i++)
{
lowcost[i] = G.arc[][i];//将vo相关顶点的权值存入lowcost数组
adjvex[i] = ;//置所有下标为v0
}
for(i = ; i < G.numVertexes; i++) //最小生成树开始辽
{
mini = INFITINY; //先把权值的最小值置为无限大
j = ;
k = ;
while(j < G.numVertexes)
{
if(lowcost[j] != && lowcost[j] < mini)//判断并向lowcost中添加权值
{
mini = lowcost[j];
k = j;
}
j++;
}
printf("(%d %d)",lowcost[k],k);
lowcost[k] = ;//置0表示这个定点已经完成任务,找到最小权值分支
for(j = ; j < G.numVertexes; j++)
{
if(lowcost[j] != && G.arc[k][j] < lowcost[j])
{
lowcost[j] = G.arc[k][j];
adjvex[j] = k;
}
}
}
}
简单讲解一哈:
- 4~5行,先说 adjvex[] ,这个数组要解决的问题就是存入已经安排好的那些顶点的下标,什么叫安排好了呢,比如我已经找到了 v0→v1 ,v1 就可以算是安排好了,而v0点置0则算做初始化的操作;再说 lowcost[] 这个数组,听名字就是最小权值的意思,下面讲循环的时候详解这个东西到底储存了些什么,然后每次更新之后能做什么
- 6~13行完全是初始化,要注意的是就是 lowcost[] 储存了邻接矩阵 v0 这一行的权值
- 14~38行是最小生成树的整体代码
- 16行就是每次都把最小值重置
- 19~27行,从 1 开始遍历完全,找到现在这个状态下的最小权值数,并且把这个下标用 k 存住,28行就是把权值和下标打印出来,当然也可以换成别的操作,这里不再赘述
- 然后29行,看看他都干了些什么,它把 adjvex[ k ] 置0,看一下第一点,这里表示 v1 完成任务,没有利用价值了
- 然后30~37这个循环,看看循环的条件,条件一: lowcost[ j ] != 0 ,这是啥意思,表示在没有完成任务的顶点中选择,条件二: G.arc[k][j] < lowcost[j] 这表示在刚才找到的新顶点的矩阵那一行去对应,如果有更小的权值就把 lowcost[] 更新掉,这样就保证了这个数组中同时存在好几个顶点的权值信息,还是择优录用的,然后返回循环头,再找这次的最小权值点,周而复始。
时间复杂度 O(n²) ,没啥问题辽
最后附上过程图:

谢谢大嘎
(原创)最小生成树之Prim(普里姆)算法+代码详解,最懂你的讲解的更多相关文章
- 经典问题----最小生成树(prim普里姆贪心算法)
题目简述:假如有一个无向连通图,有n个顶点,有许多(带有权值即长度)边,让你用在其中选n-1条边把这n个顶点连起来,不漏掉任何一个点,然后这n-1条边的权值总和最小,就是最小生成树了,注意,不可绕成圈 ...
- MST最小生成树及Prim普鲁姆算法
MST在前面学习了Kruskal算法,还有一种算法叫做Prim的.这两者的区别是Prim算法适合稠密图,比如说鸟巢这种几乎所有点都有相连的图.其时间复杂度为O(n^2),其时间复杂度与边的数目无关:而 ...
- 图->连通性->最小生成树(普里姆算法)
文字描述 用连通网来表示n个城市及n个城市间可能设置的通信线路,其中网的顶点表示城市,边表示两城市之间的线路,赋于边的权值表示相应的代价.对于n个定点的连通网可以建立许多不同的生成树,每一棵生成树都可 ...
- 最小生成树---普里姆算法(Prim算法)和克鲁斯卡尔算法(Kruskal算法)
普里姆算法(Prim算法) #include<bits/stdc++.h> using namespace std; #define MAXVEX 100 #define INF 6553 ...
- 查找最小生成树:普里姆算法算法(Prim)算法
一.算法介绍 普里姆算法(Prim's algorithm),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之 ...
- ACM第四站————最小生成树(普里姆算法)
对于一个带权的无向连通图,其每个生成树所有边上的权值之和可能不同,我们把所有边上权值之和最小的生成树称为图的最小生成树. 普里姆算法是以其中某一顶点为起点,逐步寻找各个顶点上最小权值的边来构建最小生成 ...
- 普里姆算法(Prim)
概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图(带权图)里搜索最小生成树.即此算法搜索到的边(Edge)子集所构成的树中,不但包括了连通图里的所有顶点(Vertex)且其所有边的权 ...
- HDU 1879 继续畅通工程 (Prim(普里姆算法)+Kruskal(克鲁斯卡尔))
继续畅通工程 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- Prim算法(普里姆算法)
描述: 一个连通图的生成树是指一个极小连通子图,它含有图中的全部顶点,但只有足以构成一棵树的 n-1 条边.我们把构造连通网的最小代价生成树成为最小生成树.而Prim算法就是构造最小生成树的一种算法. ...
随机推荐
- CentOS 7设置网卡开机自动启用
一.查看网卡配置 root权限 [root@dbsyn ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue ...
- ABAP术语-Call Transaction
Call Transaction 原文:http://www.cnblogs.com/qiangsheng/archive/2008/01/15/1039270.html A data transfe ...
- 路由器基础设置之ospf
我们将以上面的拓扑图来进行实验,要用ospf的协议达到全网互通的效果 router1: enable 进入特权模式 config t 进入全局配置模式 interface L0 ip address ...
- sax技术解析xml下jaxp解析器详细代码
*解析xml的两种技术dom和sax dom:根据xml的层级结构在内存中分配一个树形结构,把xml标签,属性,文本封装成对象. sax方式:事件驱动,边读边解析. 在javax.xml.parser ...
- 部署node api的二三事
当接到node开发node api的时候,我就想用docker来部署,众所周知,node的版本更新迭代很快.很多以前需要babel后才能采用的方法正在不断被node 原生的支持.如果随便更换生产服务器 ...
- 《高性能MySQL》笔记——MySQL建表数据类型的选择
前段时间看了<高性能MySQL>中的选择优化的数据类型,这里主要是做一下笔记. 首先数据选择有几个简单原则: 更小的通常更好.一般情况下,应该尽量使用可以正确存储数据的最小数据类型.例如只 ...
- ECSHOP和SHOPEX快递单号查询中通插件V8.6专版
发布ECSHOP说明: ECSHOP快递物流单号查询插件特色 本ECSHOP快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅 ...
- 《linux设备驱动开发详解》笔记——15 linux i2c驱动
结合实际代码和书中描述,可能跟书上有一定出入.本文后续芯片相关代码参考ZYNQ. 15.1 总体结构 如下图,i2c驱动分为如下几个重要模块 核心层core,完成i2c总线.设备.驱动模型,对用户提供 ...
- java8lambda表达式初识
一.函数式接口 只有一个 抽象方法 的 接口 叫函数式接口 /** * @auther hhh * @date 2018/12/24 22:20 * @description 函数式接口:只有 一个 ...
- 【转】Linux系统安装Redis详细过程
本文来源 https://blog.csdn.net/qq_20989105/article/details/76390367 ,转载前请先联系原作者并声明出处. 一.安装gcc 1.Redis在li ...