普里姆算法(Prim算法)

简介

普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小。该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(英语:Vojtěch Jarník)发现;并在1957年由美国计算机科学家罗伯特·普里姆(英语:Robert C. Prim)独立发现;1959年,艾兹格·迪科斯彻再次发现了该算法。因此,在某些场合,普里姆算法又被称为DJP算法、亚尔尼克算法或普里姆-亚尔尼克算法。

算法描述

  1. 输入:一个加权连通图,其中顶点集合为V,边集合为E;
  2. 初始化:VnewV_{new}Vnew​ = {x},其中x为集合V中的任一节点(起始点),EnewE_{new}Enew​ = {},为空;
  3. 重复下列操作,直到VnewV_{new}Vnew​= V:
    a.在集合E中选取权值最小的边 < u, v>,其中u为集合VnewV_{new}Vnew​中的元素,而v不在VnewV_{new}Vnew​集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
    b.将v加入集合VnewV_{new}Vnew​中,将< u, v>边加入集合EnewE_{new}Enew​中;
  4. 输出:使用集合VnewV_{new}Vnew​和EnewE_{new}Enew​来描述所得到的最小生成树。

图示

简略证明

反证法:假设prim生成的不是最小生成树

  1. 设prim生成的树为G0
  2. 假设存在GminG_{min}Gmin​使得cost(GminG_{min}Gmin​)< cost(G0G_{0}G0​) 则在GminG_{min}Gmin​中存在< u,v>不属于G0G_{0}G0​
  3. 将< u,v>加入G0G_{0}G0​中可得一个环,且< u,v>不是该环的最长边(这是因为< u,v>∈GminG_{min}Gmin​)
  4. 这与prim每次生成最短边矛盾
  5. 故假设不成立,命题得证

基本操作函数

prim(n):建立最小生成树,并输出其权值和

代码模板(含详细注释)

这里用 http://poj.org/problem?id=1258 作为模板题

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 110   //最多顶点数
#define MAX 0x3f3f3f3f  //模拟无穷大
int map[N][N];  //存储各顶点间的权值
int flag[N];    //标记是否已纳入树
int dis[N];     //已纳入点和其余各点的最小权值
int prim(int n)        //普利姆函数
{int i, j;int now;    //记录新纳入的点int min;    //记录新纳入的点到其余已纳入的点的最小权值int sum = 0;    //最小生成树权值和memset(dis, MAX, sizeof(dis));  //初始化dis数组为无穷大memset(flag, 0, sizeof(flag));  //初始化flag数组,0表示此点未被纳入/*这里随机选取了1号点为初始时被纳入的顶点*/for(i = 1; i <= n; i++)dis[i] = map[1][i];     //与1号点与其他点的权值存入dis数组dis[1] = 0;         //一号点到其本身的权值为0flag[1] = 1;        //标记为已纳入for(i = 1; i < n; i++){         //除去初始时随机纳入的点还有n-1个点应被纳入now = min = MAX;            //初始为无穷大表示两点间无通路for(j = 1; j <= n; j++){    //遍历if(flag[j] == 0){if(dis[j] < min){   //寻找与已纳入各点权值最小的点now = j;min = dis[j];}}}if(now == MAX)      //若now等于max,则证明所有与初始时纳入的点连通的点已全被纳入break;sum += min;     //将找到的点纳入并标记flag[now] = 1;for(j = 1; j <= n; j++){/*遍历比较之前纳入点到未纳入点的权值的最小值与刚纳入点到未纳入点的权值并用dis[j]存储新的最小值*/if(flag[j] == 0)if(dis[j] > map[now][j])dis[j] = map[now][j];}}if(i == n)      //若i等于n则证明已经建立最小生成树return sum;elsereturn -1;
}
int main(void)
{int i, j, k;int n;      //顶点数while(scanf("%d", &n) != EOF){for(i = 1; i <= n; i++)for(j = 1; j <= n; j++)scanf("%d", &map[i][j]);  //输入i和j之间的距离if((k = prim(n)) != -1) //调用prim函数printf("%d\n", k);elseprintf("烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫\n");}return 0;
}

模板题样例图解

运行示例

普里姆算法(Prim算法)相关推荐

  1. 普里姆(Prim)算法

    普里姆(Prim)算法 普里姆(Prim)算法思想 普里姆(Prim)算法是一某个顶点为起点,逐步找各顶点最小权值的边来构建最小生成树. 换一种说法: 从任意一顶点 v0 开始选择其最近顶点 v1 构 ...

  2. 普里姆(Prim)求最小生成树

    一.普里姆(Prim)算法 1.基本思想:设G=(V, E)是具有n个顶点的连通网,T=(U, TE)是G的最小生成树, T的初始状态为U={u0}(u0∈V),TE={},重复执行下述操作:在所有u ...

  3. 普里姆(Prim)算法 Java实现(最小生成树)

    构造最小生成树的Prim算法(从顶点的思想) 自己的话描述: 1. 从任意一个顶点开始.临时权值数组就是该顶点的权值数组. 2. 找到一条权重最小的边,然后把这两个顶点视为一个顶点,新加入的顶点在临时 ...

  4. 普里姆(Prim)算法(精讲)

    当我们想要找连通网的最小生成树时,经典的有两种算法,普里姆算法和克鲁斯卡尔算法,这里我们介绍的便是普里姆算法. 普里姆算法流程: ps:上图来自于大话数据结构 1.假设我们找顶点V0作为首个遍历的顶点 ...

  5. 普里姆(Prim)算法(P算法):修路问题

    1,应用场景-修路问题 如图,此时有7个村庄['A', 'B', 'C', 'D', 'E', 'F', 'G'],现在需要把这7个村庄连通 村庄之间的连接线表示可能修路的图示,权值表示举例 此时,如 ...

  6. 普里姆 克鲁斯卡尔算法

    一.简介 连通图:任意2节点之间都有路径相通 最小生成树:最小权重生成树 一个 n 结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边(n-1). 最 ...

  7. 四、最小生成树——普里姆(Prim)算法

    一个连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边,那么我们把构造连通图网的最小代价生成树称为最小生成树(就是n个顶点,用n-1条边全部连接起来,并且使得权 ...

  8. 最小生成树(普里姆算法【Prim】与克鲁斯卡尔算法【Kruskal】)

    写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站.博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事 ...

  9. 大话数据结构-普里姆算法(Prim)和克鲁斯卡尔算法(Kruskal)

    5 最小生成树   构造连通网的最小代价生成树称为最小生成树,即Minimum Cost Spanning Tree,最小生成树通常是基于无向网/有向网构造的.   找连通网的最小生成树,经典的有两种 ...

  10. prim算法(普里姆算法)详解

    prim算法(普里姆算法)详解 了解了什么是最小生成树后,本节为您讲解如何用普里姆(prim)算法查找连通网(带权的连通图)中的最小生成树. 普里姆算法查找最小生成树的过程,采用了贪心算法的思想.对于 ...

最新文章

  1. js 文件不让通过地址访问_区块链与以太坊实战(5):访问以太坊节点的N中方式...
  2. PIE SDK打开栅格数据
  3. https refused 解决方法
  4. 【Java案例】-Jedis操作redis教程
  5. 在Latex中插入Python代码
  6. CAN总线技术 | 物理层03 - 采样点
  7. 【kafka】Kafka 源码解析:Group 协调管理机制
  8. Android模块化之MicroModule(微信Pins工程) 1
  9. simulink 28335 代码_simulink建立自己的模块库
  10. Hystrix服务降级、服务熔断介绍
  11. xampp 运行 yaf框架
  12. 基于各系统平台(RedHat Linux、SUSE Linux、CentOS、SUN Solaris10) FTP服务的配
  13. 仿小米商城html网页源码
  14. PLC基本指令系统优势
  15. 安全管家安卓_网速管家安卓5.4版本全面上线,多场景网络体验全面升级
  16. eaxsinbx_二次微分方程的通解
  17. 如何打开RAR文件?
  18. 地表最强!北大清华合力打造通用人工智能实验班,朱松纯教授领衔
  19. JAVA萌新学习day17.18天 数据库MySQL
  20. 第一课:初识Java

热门文章

  1. 【报告分享】母婴品牌社媒营销解决方案(2021)-微播易(附下载)
  2. 核心素养进课堂计划单小学计算机,核心素养进课堂的计划单.doc
  3. 程序员休假时可以去的两个地方,超级治愈。
  4. 被扣1000块工资了
  5. Cannot resolve symbol ‘redis‘
  6. MongoDB 组合多个条件查询(and、and、in、gte、gte、lte)
  7. php base64 站长工具,关键词优化难易分析_SEO优化难度分析 - 站长工具
  8. 维智科技位列顶尖BI服务商,时空AI赋能商业生态数据价值最大化
  9. ps原画基础教程 怎么自学原画
  10. js输入一个年月,输出这个月有多少天