最小生成树即在一个图中用最小权值的边将所有点连接起来。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最小生成树的更多相关文章

  1. prim求MST

    PRIM==>>MST模板 #include <iostream> using namespace std; #define typec int #define V 3 con ...

  2. Borůvka (Sollin) 算法求 MST 最小生成树

    基本思路: 用定点数组记录每个子树的最近邻居. 对于每一条边进行处理: 如果这条边连成的两个顶点同属于一个集合,则不处理,否则检测这条边连接的两个子树,如果是连接这两个子树的最小边,则更新 (合并). ...

  3. MST最小生成树及Prim普鲁姆算法

    MST在前面学习了Kruskal算法,还有一种算法叫做Prim的.这两者的区别是Prim算法适合稠密图,比如说鸟巢这种几乎所有点都有相连的图.其时间复杂度为O(n^2),其时间复杂度与边的数目无关:而 ...

  4. MST最小生成树

    首先,贴上一个很好的讲解贴: http://www.wutianqi.com/?p=3012 HDOJ 1233 还是畅通工程 http://acm.hdu.edu.cn/showproblem.ph ...

  5. UVA 1151 Buy or Build (MST最小生成树,kruscal,变形)

    题意: 要使n个点之间能够互通,要使两点直接互通需要耗费它们之间的欧几里得距离的平方大小的花费,这说明每两个点都可以使其互通.接着有q个套餐可以选,一旦选了这些套餐,他们所包含的点自动就连起来了,所需 ...

  6. POJ 1789:Truck History(prim&amp;&amp;最小生成树)

    id=1789">Truck History Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17610   ...

  7. [BZOJ1937][SHOI2004]Mst最小生成树(KM算法,最大费用流)

    1937: [Shoi2004]Mst 最小生成树 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 802  Solved: 344[Submit][Sta ...

  8. 【BZOJ2238】Mst 最小生成树+LCA+堆

    [BZOJ2238]Mst Description 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影响,即被删掉的 ...

  9. 【BZOJ1937】[Shoi2004]Mst 最小生成树 KM算法(线性规划)

    [BZOJ1937][Shoi2004]Mst 最小生成树 Description Input 第一行为N.M,其中 表示顶点的数目, 表示边的数目.顶点的编号为1.2.3.…….N-1.N.接下来的 ...

随机推荐

  1. 解决:Visual Studio 启动就报错退出

    Please open an administrative CMD window and navigate to C:\Program Files (x86)\Microsoft Visual Stu ...

  2. 自动诊断档案库(ADR)学习

    (1)ADR概述 Oracle 11g的FDI(Fault Diagnosability Infrastructure)是自动化诊断方面的一个增强,其核心组件为自动诊断库(Automatic Diag ...

  3. django-模板层基础2

    1.模板的导入 {% include 模板名%} 首先在你的的项目中,需要很多地方用到同一个组件(相对于头部,你进行每个页面的切换,网页最上面的头 部不需要改变),那么这样我们可以把那个头部重新写在一 ...

  4. unexpected reloc type问题分析

    1.现象,程序在启动的时候报如下错误error while loading shared libraries: /home/test/lib/libtest.so: unexpected reloc ...

  5. linux运维、架构之路-shell编程(二)

    一.流程控制语句 1.if语句 ①if单分支:一个条件一个结果 1 2 3 4 if 条件   then      命令 fi ②if双分支:一个条件两个结果 1 2 3 4 5 6 if 条件    ...

  6. SI - 系统 - 操作系统简述 (Operating System)

    Unix 操作系统:System V.BSD Microsoft Windows Apple Mac OS Linux FreeBSD 安装 https://jingyan.baidu.com/art ...

  7. djangorestframework怎么这么好用!

    一年前就已经用过restframework, 当时觉得这个只是给web框架打辅助的, 他能实现的我也都实现(可能没有那么好用, 嘿嘿) 但是我有一种东西叫做效率, 时间就是金钱, 别人造好的就直接用就 ...

  8. PHP实现微信红包算法和微信红包的架构设计简介

    微信红包的架构设计简介: 原文:https://www.zybuluo.com/yulin718/note/93148 @来源于QCon某高可用架构群整理,整理朱玉华. 背景:有某个朋友在朋友圈咨询微 ...

  9. 微信小程序使用相机

    <view class="page-body"> <view class="page-body-wrapper"> <camera ...

  10. CentOS下安装pip

    CentOS下安装pip 通常情况下使用命令: yum -y install pip 也有可能报错,无法安装.这是应该使用第二种方法. 1.首先需要先安装扩展源EPEL: yum -y install ...