普里姆算法(Prim算法)
普里姆算法(Prim算法)
简介
普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小。该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(英语:Vojtěch Jarník)发现;并在1957年由美国计算机科学家罗伯特·普里姆(英语:Robert C. Prim)独立发现;1959年,艾兹格·迪科斯彻再次发现了该算法。因此,在某些场合,普里姆算法又被称为DJP算法、亚尔尼克算法或普里姆-亚尔尼克算法。
算法描述
- 输入:一个加权连通图,其中顶点集合为V,边集合为E;
- 初始化:VnewV_{new}Vnew = {x},其中x为集合V中的任一节点(起始点),EnewE_{new}Enew = {},为空;
- 重复下列操作,直到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中; - 输出:使用集合VnewV_{new}Vnew和EnewE_{new}Enew来描述所得到的最小生成树。
图示
简略证明
反证法:假设prim生成的不是最小生成树
- 设prim生成的树为G0
- 假设存在GminG_{min}Gmin使得cost(GminG_{min}Gmin)< cost(G0G_{0}G0) 则在GminG_{min}Gmin中存在< u,v>不属于G0G_{0}G0
- 将< u,v>加入G0G_{0}G0中可得一个环,且< u,v>不是该环的最长边(这是因为< u,v>∈GminG_{min}Gmin)
- 这与prim每次生成最短边矛盾
- 故假设不成立,命题得证
基本操作函数
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算法)相关推荐
- 普里姆(Prim)算法
普里姆(Prim)算法 普里姆(Prim)算法思想 普里姆(Prim)算法是一某个顶点为起点,逐步找各顶点最小权值的边来构建最小生成树. 换一种说法: 从任意一顶点 v0 开始选择其最近顶点 v1 构 ...
- 普里姆(Prim)求最小生成树
一.普里姆(Prim)算法 1.基本思想:设G=(V, E)是具有n个顶点的连通网,T=(U, TE)是G的最小生成树, T的初始状态为U={u0}(u0∈V),TE={},重复执行下述操作:在所有u ...
- 普里姆(Prim)算法 Java实现(最小生成树)
构造最小生成树的Prim算法(从顶点的思想) 自己的话描述: 1. 从任意一个顶点开始.临时权值数组就是该顶点的权值数组. 2. 找到一条权重最小的边,然后把这两个顶点视为一个顶点,新加入的顶点在临时 ...
- 普里姆(Prim)算法(精讲)
当我们想要找连通网的最小生成树时,经典的有两种算法,普里姆算法和克鲁斯卡尔算法,这里我们介绍的便是普里姆算法. 普里姆算法流程: ps:上图来自于大话数据结构 1.假设我们找顶点V0作为首个遍历的顶点 ...
- 普里姆(Prim)算法(P算法):修路问题
1,应用场景-修路问题 如图,此时有7个村庄['A', 'B', 'C', 'D', 'E', 'F', 'G'],现在需要把这7个村庄连通 村庄之间的连接线表示可能修路的图示,权值表示举例 此时,如 ...
- 普里姆 克鲁斯卡尔算法
一.简介 连通图:任意2节点之间都有路径相通 最小生成树:最小权重生成树 一个 n 结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边(n-1). 最 ...
- 四、最小生成树——普里姆(Prim)算法
一个连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边,那么我们把构造连通图网的最小代价生成树称为最小生成树(就是n个顶点,用n-1条边全部连接起来,并且使得权 ...
- 最小生成树(普里姆算法【Prim】与克鲁斯卡尔算法【Kruskal】)
写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站.博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事 ...
- 大话数据结构-普里姆算法(Prim)和克鲁斯卡尔算法(Kruskal)
5 最小生成树 构造连通网的最小代价生成树称为最小生成树,即Minimum Cost Spanning Tree,最小生成树通常是基于无向网/有向网构造的. 找连通网的最小生成树,经典的有两种 ...
- prim算法(普里姆算法)详解
prim算法(普里姆算法)详解 了解了什么是最小生成树后,本节为您讲解如何用普里姆(prim)算法查找连通网(带权的连通图)中的最小生成树. 普里姆算法查找最小生成树的过程,采用了贪心算法的思想.对于 ...
最新文章
- java的数组是对象吗_在Java中数组是原始类型还是对象?
- Android控件-GridView
- UML用例图总结(转)
- 【剑指offer】_16 构建乘积数组
- MySQL 全文搜索支持, mysql 5.6.4支持Innodb的全文检索和类memcache的nosql支持
- matlab+text+extent,MATLAB字体及特殊符号标示方法
- adb shell 修改文件名_shell修改文件名(一)
- mysql explain key为空_MySQL中explain的使用以及性能分析
- while正逆序的测试结果
- 如何在服务器中安装mysql 以及安装禅道
- 地铁译:Spark for python developers --- 搭建Spark虚拟环境 4...
- 七年三套房,阿里程序员炫富,努力就有回报,感谢当初的选择!
- 清理localstorage_清除浏览器localstorage的数据
- 牛逼!40行Python代码一键把html网页保存为pdf,太方便了!
- 用vue+vant框架写手机端
- logback springBoot 配置日志
- wcdma码片速率_WCDMA中3.84M码片速率的由来
- 怎么在unity中测试游戏_Unity中的性能基准测试:如何开始
- java利用ffmpeg将amr、caf转mp3格式
- [bbk5148] 第51集 - 第五章 管理内存 06