图论---最小生成树----普利姆(Prim)算法
普利姆(Prim)算法
1. 最小生成树(又名:最小权重生成树)
概念:将给出的所有点连接起来(即从一个点可到任意一个点),且连接路径之和最小的图叫最小生成树。最小生成树属于一种树形结构(树形结构是一种特殊的图),或者说是直链型结构,因为当n个点相连,且路径和最短,那么将它们相连的路一定是n-1条。
可以利用参考一个问题理解最小生成树,有n个村庄,每个村庄之间距离不同,要求村庄之间修路,每一个村庄必须与任意一个村庄联通,如何修路最省钱(修的最短)。
2. 普利姆算法介绍
利姆(Prim)算法求最小生成树,也就是在包含n个顶点的连通图中,找出只有(n-1)条边包含所有n个顶点的连通子图,也就是所谓的极小连通子图
具体过程如下:
(1)设G=(V,E)是连通网,T=(U,D)是最小生成树,V,U是顶点集合,E,D是边的集合
(2)若从顶点u开始构造最小生成树,则从集合V中取出顶点u放入集合U中,标记顶点v的visited[u]=1
(3)若集合U中顶点ui与集合V-U中的顶点vj之间存在边,则寻找这些边中权值最小的边,但不能构成回路,将顶点vj加入集合U中,将边(ui,vj)加入集合D中,标记visited[vj]=1
(4)重复步骤②,直到U与V相等,即所有顶点都被标记为访问过,此时D中有n-1条边
3.图例描述

4.Prime代码
#include <stdio.h>
#include <stdlib.h>
#include<iostream>
using namespace std; #define n 20
#define MaxNum 10000 /*定义一个最大整数*/ /*定义邻接矩阵类型*/
typedef int adjmatrix[n + 1][n + 1];
typedef struct {
int fromvex, tovex; //生成树的起点和终点
int weight; //边的权重
} Edge;
typedef Edge *EdgeNode; //定义生成树的别名
int arcnum; /*边的个数*/ /*建立图的邻接矩阵*/
void CreatMatrix(adjmatrix GA) {
int i, j, k, e;
cout<<"============================="<<endl;
cout<<"图中有"<<n<<"个顶点 "<<endl;
for(i=1; i<=n; i++) {
for(j=1; j<=n; j++) {
if(i==j) {
GA[i][j]=0; /*对角线的值置为0*/
} else {
GA[i][j]=MaxNum; /*其他位置的值置初始化为一个最大整数*/
}
}
}
cout<<"请输入边的个数"<<endl;
cin>>arcnum;
cout<<"请输入边的信息,依照起点,终点,权值的形式输入:"<<endl;
for(k=1; k<=arcnum; k++) {
cin>>i>>j>>e; /*读入边的信息*/
GA[i][j]=e;
GA[j][i]=e;
}
} /*初始化图的边集数组*/
void InitEdge(EdgeNode GE,int m) {
int i;
for(i=1; i<=m; i++) {
GE[i].weight=0;
}
} /*依据图的邻接矩阵生成图的边集数组*/
void GetEdgeSet(adjmatrix GA,EdgeNode GE) {
int i, j, k = 1;
for(i=1; i<=n; i++) {
for(j=i+1; j<=n; j++) {
if(GA[i][j] !=0 && GA[i][j] != MaxNum) {
GE[k].fromvex = i;
GE[k].tovex = j;
GE[k].weight = GA[i][j];
k++;
}
}
}
} /*按升序排列图的边集数组*/
void SortEdge(EdgeNode GE,int m) {
int i,j,k;
Edge temp;
for(i=1; i<m; i++) {
k=i;
for(j=i+1; j<=m; j++) {
if(GE[k].weight > GE[j].weight) {
k=j;
}
}
if(k!=i) {
temp = GE[i];
GE[i]=GE[k];
GE[k]=temp;
}
}
} /*利用普里姆算法从初始点v出发求邻接矩阵表示的图的最小生成树*/
void Prim(adjmatrix GA,EdgeNode T) {
int i,j,k,min,u,m,w;
Edge temp;
/*给T赋初值。相应为v1依次到其余各顶点的边*/
k=1;
for(i=1; i<=n; i++) {
if(i!=1) {
T[k].fromvex=1;
T[k].tovex=i;
T[k].weight=GA[1][i];
k++;
}
}
/*进行n-1次循环,每次求出最小生成树中的第k条边*/
for(k=1; k<n; k++) {
min=MaxNum;
m=k;
for(j=k; j<n; j++) {
if(T[j].weight<min) {
min=T[j].weight;
m=j;
}
}
/*把最短边对调到k-1下标位置*/ //可用swap替换
temp=T[k];
T[k]=T[m];
T[m]=temp;
/*把新增加最小生成树T中的顶点序号赋给j*/
j=T[k].tovex;
/*改动有关边,使T中到T外的每个顶点保持一条到眼下为止最短的边*/
for(i=k+1; i<n; i++) {
u=T[i].tovex;
w=GA[j][u];
if(w<T[i].weight) {
T[i].weight=w;
T[i].fromvex=j;
}
}
}
} /*输出边集数组的每条边*/
void OutEdge(EdgeNode GE,int e) {
int i;
printf("依照起点,终点。权值的形式输出的最小生成树为:\n");
for(i=1; i<=e; i++) {
printf("%d,%d,%d\n",GE[i].fromvex,GE[i].tovex,GE[i].weight);
}
printf("=============================\n");
} int main() {
adjmatrix GA;
Edge GE[n*(n-1)/2], T[n];
CreatMatrix(GA);
InitEdge(GE,arcnum);
GetEdgeSet(GA,GE);
SortEdge(GE,arcnum);
Prim(GA,T);
printf("\n");
OutEdge(T,n-1);
return 0;
}
图论---最小生成树----普利姆(Prim)算法的更多相关文章
- 最小生成树-普利姆(Prim)算法
最小生成树-普利姆(Prim)算法 最小生成树 概念:将给出的所有点连接起来(即从一个点可到任意一个点),且连接路径之和最小的图叫最小生成树.最小生成树属于一种树形结构(树形结构是一种特殊的图),或者 ...
- 图解最小生成树 - 普里姆(Prim)算法
我们在图的定义中说过,带有权值的图就是网结构.一个连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边.所谓的最小成本,就是n个顶点,用n-1条边把一个连通图连接 ...
- 普里姆Prim算法介绍
普里姆(Prim)算法,和克鲁斯卡尔算法一样,是用来求加权连通图的最小生成树的算法. 基本思想 对于图G而言,V是所有顶点的集合:现在,设置两个新的集合U和T,其中U用于存放G的最小生成树中的顶点,T ...
- 最小生成树-普利姆算法lazy实现
算法描述 lazy普利姆算法的步骤: 1.从源点s出发,遍历它的邻接表s.Adj,将所有邻接的边(crossing edges)加入优先队列Q: 2.从Q出队最轻边,将此边加入MST. 3.考察此边的 ...
- JS实现最小生成树之普里姆(Prim)算法
最小生成树: 我们把构造连通网的最小代价生成树称为最小生成树.经典的算法有两种,普利姆算法和克鲁斯卡尔算法. 普里姆算法打印最小生成树: 先选择一个点,把该顶点的边加入数组,再按照权值最小的原则选边, ...
- 最小生成树-普利姆算法eager实现
算法描述 在普利姆算法的lazy实现中,参考:普利姆算法的lazy实现 我们现在来考虑这样一个问题: 我们将所有的边都加入了优先队列,但事实上,我们真的需要所有的边吗? 我们再回到普利姆算法的lazy ...
- POJ-2421-Constructing Roads(最小生成树 普利姆)
Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 26694 Accepted: 11720 Description The ...
- 最小生成树——Prim(普利姆)算法
[0]README 0.1) 本文总结于 数据结构与算法分析, 源代码均为原创, 旨在 理解Prim算法的idea 并用 源代码加以实现: 0.2)最小生成树的基础知识,参见 http://blog. ...
- 图的普里姆(Prim)算法求最小生成树
关于图的最小生成树算法------普里姆算法 首先我们先初始化一张图: 设置两个数据结构来分别代表我们需要存储的数据: lowcost[i]:表示以i为终点的边的最小权值,当lowcost[i]=0说 ...
随机推荐
- 基于 Clusternet 与 OCM 打造新一代开放的多集群管理平台
背景 随着 5G.物联网设备的爆炸性增长以及智能终端不断增强的计算能力,带来了前所未有的数据量,传统的中心集中式计算捉襟见肘."新基建"战略的实施,工业互联网.车联网/自动驾驶.智 ...
- 01 CTF从0到。。。。
无意间在前段时间接触到了CTF,感觉很有意思,就参加了个单位的短期培训,并且参加了比赛,也是无意混进了决赛.感觉自己不会的还很多!SO,开始写博客开始刷题,自己很菜,不会C,不会Python,不会汇编 ...
- 问题求解与程序设计(C重新回顾:个人版)一
一.容易遗忘之转义字符 转义序列 含义 \n 换行 \t 水平制表 \\ 输出反斜杠 \a 响铃符 \'' 输出双引号 \' 输出单引号 \? 输出问号 \r 输出回车符(不换行,光标定位当前行的开始 ...
- NOIP 模拟 10 考试总结
T1 一道很妙的题,打暴力分也很多,但是考试的时候忘开 long long 了. 题解 T2 一道挺水的题,不过...(打挂了) 题解 T3 此题甚妙,转化真多,不过对思维是一个非常大的扩展 题解 考 ...
- 从350ms到80ms,揭秘阿里工程师 iOS 短视频优化方案
内容作为 App 产品新的促活点,受到了越来越多的重视与投入,短视频则是增加用户粘性.增加用户停留时长的一把利器.短视频的内容与体验直接关系到用户是否愿意长时停留,盒马也提出全链路内容视频化的规划,以 ...
- 7、二进制安装K8s之部署kube-proxy
二进制安装K8s之部署kube-proxy 1.创建配置文件 cat > /data/k8s/config/kube-proxy.conf << EOF KUBE_PROXY_OPT ...
- C# lock的语法糖原理--《.net core 底层入门》之自旋锁,互斥锁,混合锁,读写锁
在多线程环境中,多个线程可能会同时访问同一个资源,为了避免访问发生冲突,可以根据访问的复杂程度采取不同的措施 原子操作适用于简单的单个操作,无锁算法适用于相对简单的一连串操作,而线程锁适用于复杂的一连 ...
- Django常用 命令
Django常用 命令: 安装: pip install django 指定版本 pip3 install django==2.0 新建项目: django-admin.py startproject ...
- Oracle数据库 —— DML完结
时间:2016-8-18 01:17 ----------------------------------------------------------------------------停下休息的 ...
- 使用Eclipse搭建SSM框架(Spring + Spring MVC + Mybatis)
1.创建项目 1)打开Eclipse,点击File --> New --> Other 2)输入maven,找到Maven Project 3)然后一直按Next,直到出现一下界面: 4) ...