【最小生成树之Prim算法】-C++
【最小生成树之Kruskal算法】
没有看过的可以先看↑,会更简单。
【模板】最小生成树
这一篇博客主要是介绍另外一种算法:Prim算法。
prim算法就好像是一棵"生成树"在慢慢长大,从开始的一个顶点长到了n个顶点。
总结一下这个算法,将图中所有的顶点分为2类,树顶点(已被选入生成树的顶点)和非树顶点(还未被选入生成树的顶点),接下来要找出一条边添加到生成树,这需要枚举每一个树顶点到每一个非树顶点所有的边,然后最短边加入到生成树,重复操作n-1次,直到所有顶点加入到生成树中。
实现此算法时,比较了dijkstra最短路径算法,在记录的最短距离,不是每个顶点到1号顶点的距离,而是每个顶点到任意一个“树顶点”的最短距离。
时间复杂度:O(n^2)(n为顶点数)
主要思路: 通过依次加入新的最优的店来实现。用dst[i]来表示第i个点加入这棵树所需的代价。
可能有点难理解,那就画图理解:
大概如下一个无向图:
因为从任意一个顶点出发都可以生成这棵最小数,所以我们在代码中都规定从编号为1的定点开始构造。(将1打上标记)同时记录dst[1]=0;(是没有任何代价的,可以自己理解一下)
从点1出发,我们可以找到(和点1直接连接的点)有3和4,选择边权值最小的一个(1-3)那么将3也放进已经确定来源的部分(打标记)如下(同时记录dst[3]=5;)
和3有连接的点只有2,那么也打上标记.(记录dst[2]=4)
按照循环顺序,应该先找到5(记录dst[5]=5)
接下来找到4(记录dst[4]=3)
接下来找到点6(记录dst[6]=3(这样最优))
这样,每个点都加入了这棵树,所以任务完成,这棵树的最小生成树形态如下:
接下来说说代码实现。
根据我们的模拟过程,输入之后先将点1打上标记,然后在和点1有连接的所有点中找到最优点3,然后将点3打上标记,然后在和点3有连接的所有点中找到最优点2.。。。。。
发现过程规律了吗?双重循环即可解决这个问题!
我们用一个结构体+二维vector数组g来记录与点i相连的所有点及其权值。另外为了方便,我还是用pre[i]来表示是点pre[i]连接上点i进入这棵树的。
外层for(i=1->n-1)内层第一个for(j=0->g[lasti].size())确定当前每个点的最优代价(不断更新)内层第二个for(i=1->n)统计最优点即可。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int dst[5010];
int n,m;
bool s[5010];
int pre[5010];
struct node
{
int v,w;
node(){}
node(int vv,int ww)
{
v=vv,w=ww;
}
};
vector<node> g[5010];
void init()
{
for(int i=1;i<=5000;i++)
{
dst[i]=0x7f7f7f7f;
}
}
int main()
{
init();
int a,b,c;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>a>>b>>c;
g[a].push_back(node(b,c));
g[b].push_back(node(a,c));
}
s[1]=1;
dst[1]=0;
int lasti=1;
for(int k=1;k<n;k++)
{
for(int j=0;j<g[lasti].size();j++)
{
int v=g[lasti][j].v,w=g[lasti][j].w;
if(!s[v]&&w<dst[v])
{
pre[v]=lasti;
dst[v]=w;
//dst[v]+=dst[pre[v]];
}
}
int min_i=0x7f7f7f7f,min_dst=0x7f7f7f7f;
for(int i=1;i<=n;i++)
{
if(!s[i])
{
if(dst[i]<min_dst)
{
min_dst=dst[i];
min_i=i;
}
}
}
lasti=min_i;
s[min_i]=1;
printf("更新点%d加入,父节点%d\n",lasti,pre[lasti]);
}
int total=0;
for(int i=1;i<=n;i++)
{
total+=dst[i];
printf("pre[%d]=%d\n",i,pre[i]);
}
cout<<total<<endl;
return 0;
}
输入如下数据:
6 7
1 3 5
3 2 4
2 6 5
2 5 5
5 6 3
4 5 3
1 4 6
输出如下:
prim算法要嗦的大概就是这些,剩下的需要自己不断理解,希望大家在这条路上越走越远,加油!
ov.
【最小生成树之Prim算法】-C++的更多相关文章
- C++编程练习(10)----“图的最小生成树“(Prim算法、Kruskal算法)
1.Prim 算法 以某顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树. 2.Kruskal 算法 直接寻找最小权值的边来构建最小生成树. 比较: Kruskal 算法主要是针对边来展开,边数 ...
- 最小生成树一·Prim算法
描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可以拥有不止一个城市了! 但是,问题也接踵而来——小Hi现在手上拥有N座城市,且已知这N座城市中任意两座城市之间建造道 ...
- 数据结构与算法--最小生成树之Prim算法
数据结构与算法--最小生成树之Prim算法 加权图是一种为每条边关联一个权值或称为成本的图模型.所谓生成树,是某图的一棵含有全部n个顶点的无环连通子图,它有n - 1条边.最小生成树(MST)是加权图 ...
- 24最小生成树之Prim算法
最小生成树的Prim算法 思想:采用子树延伸法 将顶点分成两类: 生长点——已经在生成树上的顶点 非生长点——未长到生成树上的顶点 使用待选边表: 每个非生长点在待选边表中有一条待选边,一端连着非生长 ...
- 最小生成树的Prim算法
构造最小生成树的Prim算法 假设G=(V,E)为一连通网,其中V为网中所有顶点的集合,E为网中所有带权边的集合.设置两个新的集合U和T,其中集合U用于存放G的最小生成树的顶点,集合T用于 ...
- hihocoder 1097 最小生成树一·Prim算法
#1097 : 最小生成树一·Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可 ...
- 算法学习记录-图——最小生成树之prim算法
一个连通图的生成树是一个极小的连通子图,它包含图中全部的顶点(n个顶点),但只有n-1条边. 最小生成树:构造连通网的最小代价(最小权值)生成树. prim算法在严蔚敏树上有解释,但是都是数学语言,很 ...
- Hihocoder 之 #1097 : 最小生成树一·Prim算法 (用vector二维 模拟邻接表,进行prim()生成树算法, *【模板】)
#1097 : 最小生成树一·Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可 ...
- hihocoder hiho一下 第二十六周 最小生成树一·(Prim算法)
题目1 : 最小生成树一·Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可以拥 ...
- 无向图最小生成树(prim算法)
普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小.该算法于1930年由捷 ...
随机推荐
- 8086 CPU 寄存器简介(超详细,图文并茂)
http://www.cnblogs.com/BoyXiao/archive/2010/11/20/1882716.html
- 亿方云(用电话或者qq沟通是远远不够的,容易忘还不能反复催,最好的方式就是指定一个平台,团队内的人定期查看最新记录)
作者:城年链接:http://www.zhihu.com/question/20579359/answer/106319200来源:知乎著作权归作者所有,转载请联系作者获得授权. 更新,文字发完后,好 ...
- php一个不错的分页
1.分页源码 <?php class PageView{ /**页码**/ public $pageNo = 1; /**页大小**/ public $pageSize = 20; /**共多少 ...
- happy machine learning(First One)
从前几天起我就开始了愉快的机器学习,这里记录一下学习笔记,我看的是吴恩达老师的视频,这篇博客将会按吴老师的教学目录来集合各优良文章,以及部分的我的个人总结 1. 监督学习与无监督学习 监督:给定一个 ...
- Spring Framework 组件注册 之 @Component
Spring Framework 组件注册 之 @Component 写在前面 在spring大行其道的今天,对于spring的使用和掌握乃是不可缺少的必备技能.但是spring的整个体系尤为庞大,对 ...
- Scala 学习之路(六)—— 常用集合类型之 List & Set
一.List字面量 List是Scala中非常重要的一个数据结构,其与Array(数组)非常类似,但是List是不可变的,和Java中的List一样,其底层实现是链表. scala> val l ...
- spring 5.x 系列第17篇 —— 整合websocket (xml配置方式)
源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.说明 1.1 项目结构说明 项目模拟一个简单的群聊功能,为区分不同的聊 ...
- 重磅发布:阿里开源 OpenJDK 长期支持版本 Alibaba Dragonwell
原文地址:https://yq.aliyun.com/articles/694603 本文作者:阿里开源 本文来自云栖社区合作伙伴"阿里系统软件技术",了解相关信息可以关注&qu ...
- java里字节与字符的区别
当时学Java的时候没搞懂字节和字符的区别,今天看文件输入输出流的时候觉得是时候彻底把这两个概念弄懂. 首先得知道byte的概念和作用: byte即字节的意思,是java中的基本数据类型,用来申明字节 ...
- System.in 获取键盘输入
此处说明 两种使用System.in获取键盘输入的两种方法,分别是Scanner 和 InputStreamReader. 其中System.in 在System类中的定义如下: package co ...