Prim求MST最小生成树
最小生成树即在一个图中用最小权值的边将所有点连接起来。prim算法求MST其实它的主要思路和dijkstra的松弛操作十分相似
prim算法思想:
在图中随便找一个点开始这里我们假定起点为“1”,以点1为松弛点将与之相连接的点进行松弛操作并更新它们的dis值因为我们只需要连接它们的最短边因此我们只需要
"dis[ i ]=edges[pos][ i ]"(记录松弛点到与之相连的节点的边权) 接下来的操作和dijkstra一样我们进行贪心找到距松弛点最近的点并记录下它的坐标,而且使之成为下一个松弛点
然后我们循环n遍(一共n个节点) 最后它们的dis值就为构成一棵树的最短边。
图解:
由上面的贪心过程可以得到prim的工作原理就是将所有点作为松弛点对每个点的最短连接边进行松弛因此这些边可以构成一棵最小的树
代码:
for(int k=;k<=n;k++)
{
insert minn=INF,pos;
for(int i=;i<=n;i++)
{
if(!vis[i]&&dis[i]<minn)//寻找松弛点
{
pos=i;
minn=dis[i];
}
}
}
贪心代码:
for(int i=;i<=n;i++)
{
if(!vis[i]&&dis[i]>edges[pos][i])//prim核心代码
dis[i]=edges[pos][i];//贪心将每个点更新与之相连的最小的值
}
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdio>
#include <iomanip>
using namespace std;
typedef int insert;
#define in cin
const int INF=0x3f3f3f3f;
const int N=+;
insert edges[N][N],dis[N],vis[N];
insert n,m,x,y,z;
long long sum;
void value()
{
memset(edges,INF,sizeof(edges));
memset(dis,INF,sizeof(dis));
for(int i=;i<=m;i++)
{
in>>x>>y>>z;
if(edges[x][y]>z||edges[y][x]>z)
{
edges[x][y]=z;
edges[y][x]=z;
}
}
dis[]=;
return;
}
void prim()
{
for(int k=;k<=n;k++)
{
insert minn=INF,pos;
for(int i=;i<=n;i++)
{
if(!vis[i]&&dis[i]<minn)
{
pos=i;
minn=dis[i];
}
}
vis[pos]=true;
for(int i=;i<=n;i++)
{
if(!vis[i]&&dis[i]>edges[pos][i])
dis[i]=edges[pos][i];
}
}
return;
}
int main()
{
in>>n>>m;
value();
prim();
for(int i=;i<=n;i++)
sum+=dis[i];
cout<<"最小生成树的总权值"<<endl;
cout<<sum<<endl;
cout<<"每个点的最短边"<<endl;
for(int i=;i<=n;i++)
cout<<dis[i]<<" ";
return ;
}
但是如果用邻接矩阵存图既浪费空间又存不了大图所以便有了以下vector邻接表版本
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <stack>
using namespace std;
typedef int insert;
#define in cin
#define out cout
const int INF=0x3f3f3f3f;
const int N=2e5+;
insert n,m,x,y,z,dis[N],sum,startpoint;
bool vis[N];
struct Node
{
insert to,w;
};
vector<struct Node> vt[N];
void inital_value()
{
memset(dis,INF,sizeof(dis));
for(int i=;i<=m;i++)
{
cin>>x>>y>>z;
struct Node now;
now.to=y;now.w=z;
vt[x].push_back(now);
now.to=x;
vt[y].push_back(now);
}
dis[startpoint]=;
return;
} void prim()
{
for(int k=;k<=n;k++)
{
insert minn=INF,pos;
for(int i=;i<=n;i++)
{
if(!vis[i]&&dis[i]<minn)
{
minn=dis[i];
pos=i;
}
}
vis[pos]=true;
for(int i=;i<vt[pos].size();i++)
{
if(!vis[vt[pos][i].to]&&dis[vt[pos][i].to]>vt[pos][i].w)
dis[vt[pos][i].to]=vt[pos][i].w;
}
}
return;
}
int main()
{
in>>n>>m>>startpoint;
inital_value();
prim();
for(int i=;i<=n;i++)
sum+=dis[i];
for(int i=;i<=n;i++)
cout<<startpoint<<"-->"<<i<<" "<<dis[i]<<endl;
cout<<"最小生成树的总边权:"<<endl;
cout<<sum<<endl;
return ;
}
Prim求MST最小生成树的更多相关文章
- prim求MST
PRIM==>>MST模板 #include <iostream> using namespace std; #define typec int #define V 3 con ...
- Borůvka (Sollin) 算法求 MST 最小生成树
基本思路: 用定点数组记录每个子树的最近邻居. 对于每一条边进行处理: 如果这条边连成的两个顶点同属于一个集合,则不处理,否则检测这条边连接的两个子树,如果是连接这两个子树的最小边,则更新 (合并). ...
- MST最小生成树及Prim普鲁姆算法
MST在前面学习了Kruskal算法,还有一种算法叫做Prim的.这两者的区别是Prim算法适合稠密图,比如说鸟巢这种几乎所有点都有相连的图.其时间复杂度为O(n^2),其时间复杂度与边的数目无关:而 ...
- MST最小生成树
首先,贴上一个很好的讲解贴: http://www.wutianqi.com/?p=3012 HDOJ 1233 还是畅通工程 http://acm.hdu.edu.cn/showproblem.ph ...
- UVA 1151 Buy or Build (MST最小生成树,kruscal,变形)
题意: 要使n个点之间能够互通,要使两点直接互通需要耗费它们之间的欧几里得距离的平方大小的花费,这说明每两个点都可以使其互通.接着有q个套餐可以选,一旦选了这些套餐,他们所包含的点自动就连起来了,所需 ...
- POJ 1789:Truck History(prim&&最小生成树)
id=1789">Truck History Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 17610 ...
- [BZOJ1937][SHOI2004]Mst最小生成树(KM算法,最大费用流)
1937: [Shoi2004]Mst 最小生成树 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 802 Solved: 344[Submit][Sta ...
- 【BZOJ2238】Mst 最小生成树+LCA+堆
[BZOJ2238]Mst Description 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影响,即被删掉的 ...
- 【BZOJ1937】[Shoi2004]Mst 最小生成树 KM算法(线性规划)
[BZOJ1937][Shoi2004]Mst 最小生成树 Description Input 第一行为N.M,其中 表示顶点的数目, 表示边的数目.顶点的编号为1.2.3.…….N-1.N.接下来的 ...
随机推荐
- js函数在frame中的相互的调用
框架编程概述一个HTML页面可以有一个或多个子框架,这些子框架以<iframe>来标记,用来显示一个独立的HTML页面.这里所讲的框架编程包括框架的自我控制以及框架之间的互相访问,例如从一 ...
- PLSQL 禁用所有约束,启用约束,索引,触发器等
--禁用外键和触发器 SET SERVEROUTPUT ON SIZE 50000BEGINfor c in (select 'ALTER TABLE '||TABLE_NAME||' DISABLE ...
- ffmpeg视频和声音
推送视频和声音 ffmpeg -f dshow -i video="screen-capture-recorder" -f dshow -i audio="内装麦克风 ( ...
- SQL Server笔记——sql语句创建数据库
MS SQLServer的每个数据库包含: 1个主数据文件(.mdf)必须. 1个事务日志文件(.ldf)必须. 可以包含: 任意多个次要数据文件(.ndf) 多个事务日志文件 CREATE DATA ...
- 大专生自学web前端前前后后
先做个自我介绍,我13年考上一所很烂专科民办的学校,学的是生物专业,具体的学校名称我就不说出来献丑了.13年我就辍学了,我在那样的学校,一年学费要1万多,但是根本没有人学习,我实在看不到希望,我就退学 ...
- zepto 基础知识(4)
61.prev prev() 类型:collection prev(selector) 类型:collection 获取对相集合中每一个元素的钱一个兄弟节点,通过选择器来进行过滤 62.prev pr ...
- oracle的局部本地分区索引
环境:oracle 12.2.0.1 注:未确定10g,11g是否有这些特性.现在基本不用10g,主要用12c,11g. 毫无疑问,这种 特性对于dba或者实施人员而言显得很重要,尤其当你的数据库主要 ...
- solr6.6教程-core的添加(二)
1.什么是core core是solr的一个索引库,可以理解为一个数据库,core可以根据需要,创建多个. 2.创建core 首先进入到solrhome文件夹(D:\solrhome),创建一个文件夹 ...
- MFC下的DLL编程学习
1.DLL库与LIB库对比: 静态链接库Lib(Static Link Library),是在编译的链接阶段将库函数嵌入到应用程序的内部.如果系统中运行的多个应用程序都包含所用到的公共库函数,则必然造 ...
- 【tp5.1】composer安装PHPExcel以及导入\导出Excel
一.安装PHPExcel 1.下载:PHPExcel https://github.com/PHPOffice/PHPExcel 2.解压后:Classes文件夹改名为PHPExcel 3.把文件夹 ...