转自:ivy-end

http://www.ivy-end.com/archives/943

背景

最小生成树(Minimum Spanning Trees),简称MST。是图论中一个非常重要的概念。解决这个问题有两种算法,今天暂且先来讨论一下Prim Algorithm。不做特别说明,讨论的都是无向图。

首先介绍一下最小生成树的概念,我们知道,图可以这样定义 G=(V,E) ,其中 G 表示图,V 表示顶点集合,E 表示边集合。最小生成树是这样一棵树,它满足:

通俗地讲,就是使得图GG连通时,所选取的边的长度的和最小。

如上图,加粗的路径就是在最小生成树上的路径。

算法讲解:

现在,我们开始讨论Prim Algorithm。这个算法可以分为下面几个步骤:

将顶点集 V 分成两个集合 A 和 B,其中集合 A 表示目前已经在MST中的顶点,而集合 B 则表示目前不在 MST 中的顶点。

寻找与集合 A 连通的最短的边 (u,v),将这条边加入最小生成树中。(此时,与(u,v) 相连的顶点,不妨设为 Bi,也应加入集合 A 中)重复第二步,直至集合 B 为空集。

算法的大体思想就是这样了。为了方便理解,我们先来看一下下面一张图片:

对照上面的图片,想必对于Prim Algorithm也有了一定的理解。

下面我们来设计算法,显然,我们需要遍历集合 A 中所有顶点及与之相连的边,取连接到集合B的权值最小的边,加入最小生成树。这样一来,复杂度将达到 O(n3)。

我们可以对这个想法进行优化。我们维护一 pCost[i] 数组,用来表示从集合A到与之相邻的节点的最小费用。这样,我们只要每次取这个数组中的最小值,把它在集合B中所对应的结点Vi加入到集合A中。

每次加入结束以后,都要更新pCost[i]数组。即枚举所有与结点Vi相连的边,判断是否比pCost[i]数组中的最小费用小,如果比它小,则更新。这样可以将算法优化到O(n2)。

代码如下:

#include <iostream>

#include <memory.h>

#include <vector>

using namespace std;

const int MAX = 1024;

const int INF = 2147483647; // 设置最大权值

int N, M;

vector<pair<int, int> > pMap[MAX]; // 邻接表

void Prim();

int main()

{

cin >> N >> M;

for(int i = 1; i <= M; i++)

{

int u, v, w;

cin >> u >> v >> w;

pMap[u].push_back(make_pair(v, w));

pMap[v].push_back(make_pair(u, w));

}

Prim();

return 0;

}

void Prim()

{

int nCost = 0;

vector<int> pMST; // 储存MST的结点

int pCost[MAX]; // 储存与集合A相邻的顶点的最小权值,0表示该结点已经在MST中

pMST.push_back(1); // 将结点1加入MST

pCost[1] = 0;

for(int i = 2; i <= N; i++) // 初始化,切记要将除1以外的都置为INF

{ pCost[i] = INF; }

for(int i = 0; i < pMap[1].size(); i++) // 处理与结点1相连的顶点

{ pCost[pMap[1][i].first] = pMap[1][i].second; }

for(int i = 1; i <= N - 1; i++) // 剩余N-1个顶点,循环N-1次

{

int nVertex = 0, nWeight = INF; // 用于寻找最短的边

for(int j = 1; j <= N; j++)

{

if(nWeight > pCost[j] && pCost[j] != 0)

{

nVertex = j;

nWeight = pCost[j];

}

}

pCost[nVertex] = 0;

pMST.push_back(nVertex); // 将节点nVertex加入MST

nCost += nWeight; // 计算MST的费用

for(int j = 0; j < pMap[nVertex].size(); j++) // 更新pCost数组

{

if(pCost[pMap[nVertex][j].first] != 0 &&

pCost[pMap[nVertex][j].first] > pMap[nVertex][j].second)

{

pCost[pMap[nVertex][j].first] = pMap[nVertex][j].second;

}

}

}

cout << "MST Cost is " << nCost << endl;

cout << "The vertexs in MST are ";

for(int i = 0; i < pMST.size(); i++)

{ cout << pMST[i] << " "; }

cout << endl;

}

Prim 算法及其高效实现相关推荐

  1. prim算法_历时两月,终拿字节跳动offer,算法面试题分享「带答案」

    欢迎关注专栏<Java架构筑基>--专注于Java技术的研究与分享! Java架构筑基​zhuanlan.zhihu.com Java架构筑基--专注于Java技术的研究与分享! 后续文章 ...

  2. Prim算法、Kruskal算法

    文章目录 Prim算法 Kruskal算法 主要内容: Prim算法 最小生成树对应的问题一般都是无向图,最小生成树所构成的图总边权之和最小,但不能是环,否则不能称之为"最小". ...

  3. 村村通工程(Prim算法)

    目录 题目描述 思路分析 AC代码 题目描述 "村村通"是国家一个系统工程,其包涵有:公路.电力.生活和饮用水.电话网.有线电视网.互联网等等. 村村通公路工程,是国家为构建和谐社 ...

  4. 数据结构与算法(7-3)最小生成树(普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法)

    目录 一.最小生成树简介 二.普里姆算法(Prim) 1.原理 2.存储 2-1.图顶点和权: 2-3. 最小生成树: 3.Prim()函数 3-1.新顶点入树 3-2.保留最小权 3-3. 找到最小 ...

  5. 基本数据结构(图: 基本结构,DFS,prim算法, kruskal算法)

    #include <iostream> using namespace std; //约定: //1. 图是由很多节点(VERTEX)构成的, 因此图结构是由一个VERTEX的链表构成的, ...

  6. 【数据结构】最小生成树 Prim算法 Kruskal算法

    最小生成树应用场景: 假设以下场景,有一块木板,板上钉上一些钉子,这些钉子可以由一些细绳连接起来.假设每个钉子可以通过一根或者多根细绳连接起来,那么一定存在这样得情况,即用最少的细绳把所有的钉子连接起 ...

  7. HDU1863(Prim算法)

    方法一:Prim算法 #include<iostream> #include<algorithm> #include<cstring> #include<ve ...

  8. 生成树的概念,最小生成树Prim算法 Kruskal算法

    求解最小生成树可以用Prim算法 Kruskal算法

  9. 三十七、Prim算法--求解最小生成树

    一.Prim算法介绍 普利姆(Prim)算法求最小生成树,也就是在包含 n 个顶点的连通图中,找出只有(n-1)条边包含所有 n 个顶点的 连通子图,也就是所谓的极小连通子图 普利姆的算法如下: 设 ...

最新文章

  1. 计算机键盘为啥要这样分布,你知道电脑键盘为什么这么排列吗?
  2. 浏览器老是自动跳出广告垃圾网页
  3. 带有正则表达式模式的Google Guava Cache
  4. 非常郁闷,WinForm中正常显示的自定义控件无法在WebForm中正常显示!
  5. Harmony OS — ProgressBar垂直、水平进度条
  6. Pytorch中Tensor和numpy数组的互相转化
  7. final变量属性小记
  8. Extjs 之dataview布局
  9. 用ABAP编程破解世界上最难数独游戏
  10. VUE 项目中对象与JSON格式字符串之间的转换
  11. Siemens 软件下载
  12. 对称密钥加密、非对称密钥加密、混合加密机制
  13. GNU Radio系列教程(五):初级篇之GNU Radio GRC AM发射与接收
  14. 训练一个图像分类器demo in PyTorch【学习笔记】
  15. iPhone 12 Mini、iPhone12、iPhone12 Pro、iPhone12 Max哪个颜色好看
  16. qemu内存模型(3) 内存布局初始化
  17. ROS12机器人操作系统免安装在线自主学习平台简介和官方第三方教程列表
  18. Windows共享上网的做法
  19. 编译单个java文件
  20. excel数字后边添加单位

热门文章

  1. [译]C#8.0中一个使接口更加灵活的新特性-默认接口实现
  2. .NET Core使用NPOI导出复杂Word详解
  3. 博客园升级有感一点建议
  4. 使用高性能Pipelines构建.NET通讯程序
  5. Docker最全教程之Ubuntu下安装Docker(十五)
  6. ASP.NET Core MVC 授权的扩展:自定义 Authorize 和 IApplicationModelProvide
  7. 用ASP.NET Core 2.1 建立规范的 REST API -- 保护API和其它
  8. .NET/.NET Core中更清晰的堆栈跟踪
  9. PS2019摄影后期处理(二)
  10. 淘宝网的技术发展史(一)——个人网站时代