最小生成树即在一个图中用最小权值的边将所有点连接起来。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. struts2 实现文件下载方法汇总

    http://pengranxiang.iteye.com/blog/259401 一.通过struts2提供的下载机制下载文件: 项目名为 struts2hello ,所使用的开发环境是MyEcli ...

  2. 记录使用antd时样式不生效的问题

    最近在学webpack,就配置了一个react的运行环境,为了偷懒使用了antd npm install antd 之后发现竟然tmd没有样式 谷歌之后发现好多同学都出现了这个问题,好在最后解决了 在 ...

  3. LeetCode 简单 - 最大子序和(53)

    采用动态规划方法O(n) 设sum[i]为以第i个元素结尾且和最大的连续子数组.假设对于元素i,所有以它前面的元素结尾的子数组的长度都已经求得,那么以第i个元素结尾且和最大的连续子数组实际上,要么是以 ...

  4. 2018/7/19 考试(tower,work,holes)

    noip模拟赛,挺良心的题,考的贼烂(膜一下@来日方长大佬(sdfz rank1)) 不多说了,看题吧 1.tower 题面: 铁塔(tower.pas/c/cpp) 题目描述 Rainbow和Fre ...

  5. poj_2249_Binomial Showdown

    In how many ways can you choose k elements out of n elements, not taking order into account? Write a ...

  6. Sonarqube中文插件-Linux[20180105]

    前言     上次安装了Sonarqube英文版使用起来不方便,这次为Sonarqube安装中文插件. 前期准备:     软件下载: https://github.com/SonarQubeComm ...

  7. springboot整合swagger笔记

    首先,在pom.xml中添加依赖 <!--swagger--> <dependency> <groupId>io.springfox</groupId> ...

  8. Linux运维一定要知道的六类好习惯和23个教训,避免入坑!

    Linux运维一定要知道的六类好习惯和23个教训,避免入坑! 从事运维三年半,遇到过各式各样的问题,数据丢失,网站挂马,误删数据库文件,黑客攻击等各类问题. 今天简单整理一下,分享给各位小伙伴. 一. ...

  9. React学习(4)——向服务器请求数据并显示

    本文中涉及到的技术包括:node.js/express服务器的搭建.fetch发送数据请求. 在之前的几篇文章中,介绍了如何搭建基础的React项目,以及一些简单知识,现在,我们还需要掌握如何用Rea ...

  10. NOIP模拟 candy

    题目描述 一天,小 DD 决定买一些糖果.他决定在两家不同的商店中买糖果,来体验更多的口味. 在每家商店中都有 nn 颗糖果,每颗糖果都有一个权值:愉悦度,代表小 DD 觉得这种糖果有多好吃.其中,第 ...