构造最小生成树的Prim算法
   假设G=(V,E)为一连通网,其中V为网中所有顶点的集合,E为网中所有带权边的集合。设置两个新的集合U和T,其中集合U用于存放G的最小生成树的顶点,集合T用于存放G的最小生成树中的边。令集合U的初值为U={u0}(假设构造最小生成树时是从顶点u0出发),集合T的初值为T={}。Prim算法的思想是:在连通网中寻找一个顶点落入U集,另外一个顶点落入V-U集的这个顶点加入到U集中,然后继续寻找一顶点在U集而另一顶点在V-U集且权值最小的边放入T集;如果不断重复直到U=V时,最小生成树就已经生成,这时集合T中包含了最小生成树的所有边。
 
概述:
    为实现Prim算法,需要设置两个一维数组lowcost和closevertex;其中,数组lowcost用来保存集合V-U中各顶点与集合U中各顶点所构成的边中具有最小权值的边的权值,并且一旦将lowcost[i]置为0,则表示顶点i已加入到集合U中,即该顶点不再作为寻找下一个最小权值边的顶点(只能在V-U集合寻找),否则将形成回路;也即,数组lowcost有两个功能:一是记录边的权值,二是标识U集中的顶点。数组closevertex也有两个功能:一是用来保存依附于该边在集合U中的顶点,即若closevertex[i]的值为j,则表示边(i,j)中的顶点j在集合U中;二是保存构造最小生成树过程中产生的每一条边,如closevertex[i]的值为j,则表示边(i,j)是最小生成树的一条边。
    我们先设定初始状态U={u0}(u0为出发的顶点),这时置lowcost[0]为0则表示顶点u0已加入到U集中,数组lowcost其它的数组元素值则为顶点u0到其余各顶点边的权值(没有边相连则取一个极大值),同时初始化数组closevertex[i]所有数组元素值为0(即先假定所有顶点包括u0都与u0有一条边).然后不断选取权值最小的边(ui,uk)(ui->U,uk->V-U),每选取一条边就将lowlost[k]置为0,表示顶点uk已加入到集合U中.由于uk从集合V-U进入到集合U,故这两个集合中的顶点发生了变化,所以需要依据这些变化修改数组lowcost和数组closevertex中相关内容.最终数组closevertex中的边即构成一个最小生成树。
参考代码:

 #include<stdio.h>
#define MAXNODE 30
#define MAXCOST 32767 void Prim(int gm[][],int closevertex[],int n)//从存储序号为0的顶点出发建立连通网的最小生成树,gm是邻接矩阵,n为顶点个数,最终建立最小生成树存于数组closevertex中
{
int lowcost[MAXNODE];
int i,j,k,mincost;
for(i=;i<n;i++)//初始化
{
lowcost[i]=gm[][i];//边(u0,ui)的权值送lowcost[i]
closevertex[i]=;//假定顶点ui到顶点u0有一条边
}
lowcost[]=;//从序号为0的顶点u0出发生成最小生成树,此时u0已经进入U集
closevertex[]=;
for(i=;i<n;i++)//在n个顶点中生成有n-1条边的最小生成树(共n-1趟)
{
mincost=MAXCOST;//MOXCOST为一个极大的常量值
j=;k=;
while(j<n)//寻找未找到过的最小权值边
{
if(lowcost[j]!=&&lowcost[j]<mincost)
{
mincost=lowcost[j];//记下最小权值边的权值
k=j;//记下最小权值边在V-U集中的顶点序号 }
j++;//继续寻找
}
printf("Edge:(%d,%d),Wight:%d\n",k,closevertex[k],mincost);//输出最小生成树的边与权值
lowcost[k]=;//顶点k进入U集
for(j=;j<n;j++)
if(lowcost[j]!=&&gm[k][j]<lowcost[j])//若顶点k进入U集后使顶点k与另一顶点j(在V-U集中)构成的边权值
{ //变小则改变lowcost[j]为这个小值,并将此最小权值的边(j,k)记入closevertex数组
lowcost[j]=gm[k][j];
closevertex[j]=k;
}
}
} void main()
{
int closevertex[MAXNODE];//存放最小生成树所有边的数组
int g[][]={{,,,,,},{,,,,,},{,,,,,},
{,,,,,},{,,,,,},{,,,,,}};
Prim(g,closevertex,);//生成最小生成树
}

输出:

连接图和对应邻接矩阵如下:

执行Prim算法产生最小生成树的分析过程见表,“---"标记的权值为每一趟所找到的最小权值。图中最小生成树每一步生长示意a~f分别对应表中的(1)~(6)趟:(1)为初始状态,(2)到(6)为生成n-1条边的n-1趟生长过程。


    
最小生成树的每一步生长情况如下图所示。其中带阴影的顶点属于U集,不带阴影的顶点属于V-U集;虚线边为待查的满足一顶点属于U集而另一顶点属于V-U集的边,而实线边则为已找到的最小生成树中的边。

最小生成树的Prim算法的更多相关文章

  1. C++编程练习(10)----“图的最小生成树“(Prim算法、Kruskal算法)

    1.Prim 算法 以某顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树. 2.Kruskal 算法 直接寻找最小权值的边来构建最小生成树. 比较: Kruskal 算法主要是针对边来展开,边数 ...

  2. 最小生成树一·Prim算法

    描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可以拥有不止一个城市了! 但是,问题也接踵而来——小Hi现在手上拥有N座城市,且已知这N座城市中任意两座城市之间建造道 ...

  3. 数据结构与算法--最小生成树之Prim算法

    数据结构与算法--最小生成树之Prim算法 加权图是一种为每条边关联一个权值或称为成本的图模型.所谓生成树,是某图的一棵含有全部n个顶点的无环连通子图,它有n - 1条边.最小生成树(MST)是加权图 ...

  4. 24最小生成树之Prim算法

    最小生成树的Prim算法 思想:采用子树延伸法 将顶点分成两类: 生长点——已经在生成树上的顶点 非生长点——未长到生成树上的顶点 使用待选边表: 每个非生长点在待选边表中有一条待选边,一端连着非生长 ...

  5. hihocoder 1097 最小生成树一·Prim算法

    #1097 : 最小生成树一·Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可 ...

  6. 算法学习记录-图——最小生成树之prim算法

    一个连通图的生成树是一个极小的连通子图,它包含图中全部的顶点(n个顶点),但只有n-1条边. 最小生成树:构造连通网的最小代价(最小权值)生成树. prim算法在严蔚敏树上有解释,但是都是数学语言,很 ...

  7. Hihocoder 之 #1097 : 最小生成树一·Prim算法 (用vector二维 模拟邻接表,进行prim()生成树算法, *【模板】)

    #1097 : 最小生成树一·Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可 ...

  8. hihocoder hiho一下 第二十六周 最小生成树一·(Prim算法)

    题目1 : 最小生成树一·Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可以拥 ...

  9. 无向图最小生成树(prim算法)

    普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小.该算法于1930年由捷 ...

随机推荐

  1. slf4j使用log4j学习笔记

    一,介绍 SLF4J 简单日记门面(Facade)SLF4J是为各种loging APIs提供一个简单统一的接口,从而使得最终用户能够在部署的时候配置自己希望的loging APIs实现. Loggi ...

  2. Python 日期时间相关

    #calendar日历模块 import calendar #calendar() 获取一年日历 result = calendar.calendar(2018,w = 2,l = 1,c = 6,m ...

  3. JavaScript(二):对象、注释、事件!

    对象 JavaScript的一个重要功能就是面向对象的功能,通过基于对象的程序设计,可以用更直观.模块化和可重复使用的方式进行程序开发. 一组包含数据的属性和对属性中包含数据进行操作的方法,称为对象. ...

  4. Visual Studio调试之断点技巧篇补遗

    原文链接地址:http://blog.csdn.net/Donjuan/article/details/4649372 讲完Visual Studio调试之断点技巧篇以后,翻翻以前看得一些资料和自己写 ...

  5. 微信小程序base64编码解码以及utf-8解码

    function base64_encode (str) { // 编码,配合encodeURIComponent使用 var c1, c2, c3; var base64EncodeChars = ...

  6. Vim使用小记(二)插件管理

    By francis_hao    Mar 8,2017 Vundle Vundle,全称为Vim bundle,是一个插件管理器.可以对vim插件进行安装和卸载. Vundle的安装方法看这里[参考 ...

  7. mysql5.7.22以上版本忘记密码时这样修改

    1.关闭mysql服务 net stop mysql 2.找到mysql安装路径找到 my.ini 打开在 [mysqld] 下添加 skip-grant-tables 跳过密码校验 3.登陆mysq ...

  8. [spoj DISUBSTR]后缀数组统计不同子串个数

    题目链接:https://vjudge.net/contest/70655#problem/C 后缀数组的又一神奇应用.不同子串的个数,实际上就是所有后缀的不同前缀的个数. 考虑所有的后缀按照rank ...

  9. git学习,哇瑟说实话我想要的

    1.Git 简介及安装Git是目前世界上最先进的分布式版本控制系统(没有之一).它的诞生也颇具传奇,Linux创始人Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!有兴趣的话, ...

  10. MongoDB加索引

    1.登陆MongoDB, 命令行在MongoDB主目录下执行:mongo -port 27017 2.切换至需要添加索引的db 并授权 use MeetingBooking db.auth({&quo ...