最小生成树即在一个图中用最小权值的边将所有点连接起来。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. 【luogu P3879 [TJOI2010]阅读理解】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3879 我先说一句: 我永远都喜欢StellaSTL 这个题,很明显就是 trie树 hash map+vec ...

  2. 【luogu P3390 矩阵快速幂】 模板

    题目链接:https://www.luogu.org/problemnew/show/P3390 首先要明白矩阵乘法是什么 对于矩阵A m*p  与  B p*n 的矩阵 得到C m*n 的矩阵 矩阵 ...

  3. Spring8中lambda表达式的学习(Function接口、BiFunction接口、Consumer接口)

    代码重构,为了确保功能的等效性,梳理代码时,发现如下代码: public SingleRespTTO fundI(SingleReqTTO request) throws Exception { re ...

  4. H5新增API和操作DOM

    博客原文:https://dobinspark.com.cn/ H5-dom扩展 获取元素 document.getElementsByClassName ('class'); //通过类名获取元素, ...

  5. Java项目中的下载 与 上传

    使用超级链接下载,一般会在浏览器中直接打开,而不是出现下载框 如果要确保出现下载框下载文件,则需要设置response中的参数: 1是要设置用附件的方式下载 Content-Disposition: ...

  6. iOS之查看代码运行的时间

    有时候我们想要准确的知道某段代码.某个循环执行的时间,然后分析效率等问题,这个时候就需要执行时间是多少.正好看到网上已经有人做了这个工作,我就直接摘下来了.正好也用了宏的方式计算时间,我们只要在需要计 ...

  7. django写一个简单的登陆注册

    要写这个,前提还是需要知道三个知识: 一个是urls.py,它是写我们的路由关系的,之前我写了通过wsgiref写一个简单的服务端,也用到了路由,就是 请求过来的url和视图函数的对应关系. 二是就是 ...

  8. Vue组件通讯黑科技

    Vue组件通讯 组件可谓是 Vue框架的最有特色之一, 可以将一大块拆分为小零件最后组装起来.这样的好处易于维护.扩展和复用等. 提到 Vue的组件, 相必大家对Vue组件之间的数据流并不陌生.最常规 ...

  9. 并查集(union-find sets)

    一.并查集及其优化 - 并查集:由若干不相交集合组成,是一种简单但是很好用的数据结构,拥有优越的时空复杂性,一般用于处理一些不相交集合的查询和合并问题. - 三种操作: 1.Make_Set(x) 初 ...

  10. shell 输出带颜色字体

    输出特效格式控制:\033[0m  关闭所有属性  \033[1m   设置高亮度  \03[4m   下划线  \033[5m   闪烁  \033[7m   反显  \033[8m   消隐  \ ...