1.prim算法分析

prim算法是用来构建MST(最小生成树)的一种基于贪心策略的算法。prim算法通过维护lowcost数组和closest数组记录每次查询的最小权值边结点。

首先,看一个示例来理解prim算法是怎样构建最小生成树的。我们现在对图a从结点V1开始构建最小生成树,在右边的是当前图的邻接矩阵。

1.先初始化一个lowcost数组和closest数组,并且让lowcost的初始值为v1行的值。让closest数组的值为v1。

2.找到lowcost数组中的最小值(权值为0表示没有边,故非0的最小值),然后记录最小权值和位置,并且加入到最小生成树中。

此时Min = 3,mindex = 3;表示(V1,V3)是本次找到的最小值边,加入MST中,并切将lowcost[mindex]的置为0,表示结点已经加入MST。

3.依据加入的结点V3,更新lowcost数组和closest数组的值。其中Closest中值代表本次查找过程中,权值为lowcost[j]的边是连接MST中哪个结点的。

4.以此循环2~3步骤,直到所有结点加入到MST中。

整个构建过程应该为下图所示:

#include<iostream>
#include<cstdio>
#include<cstring> using namespace std; #defind MAX 6;
#define MAXCOST 0x7fffffff typedef String VertexType;
typedef int EdgeType;
typedef struct {
VertexType Vex[MAX];
EdgeType Edge[MAX][MAX];
int vexnum,arcnum;
}MGragh; void prim(MGraph G, VertexType v){
int lowcost[MAX]; //lowcost数组用来更新不在MST中的结点到MST的权值最小的节点;
int closest[MAX]; //closest数组用来储存是通过哪个结点找到的最小权值边;通过<closest[i],i>找到MST的边;
int i, j,mindex,min; //mindex用来记录每次查找的最小权值边的结点; min记录每次查找到的最小权值;
//初始化 让lowcost[]的值为与v相邻的边的权值。让closest[]的值为v;
for(int i=0;i<G.vexnum;i++){
lowcost[i] = G.Edge[v][i];
closest[i] = v;
}
//扫描每个结点
for(int i=0;i<G.vexnum;i++){
min = MAXCOST;
//找到lowcost数组中的最小值,并且记录下来;
for(int j=0;j<G.vexnum;j++){
if(lowcost[j] != 0 && lowcost[j] < min ){
min = lowcost[j];
mindex = j;
}
}
//把记录的最小权值边和结点加入MST;
printf("edge(%d,%d) has join the MST,it cost %d",closest[mindex],k,min);
//更新lowcost和closest数组, 每次加入MST中结点又会产生新的边;所以需要更新lowcost;
for(int j=0;j<G.vexnum;j++){
if(G.Edge[mindex][j] !=0 && G.Edge[mindex][j] < lowcost[j]){
lowcost[j] = G.Edge[mindex][j];
closest[j] = mindex;
}
}
} }

2.Kruskal算法分析

kruskal算法也是构建生成树的一种贪心算法,它与prim算法的区别在于:kruskal主要将图中边作为处理对象。它先将图中所有的边信息储存到一个边集合中,然后选择集合中最小权值的边,并且利用vset记录相当边的2个结点是否属同一个集合,若是,则不加入MST中,若不是,则加入MST中。

我们现在对图a利用kurskal算法开始构建最小生成树,在右边的是当前图的邻接矩阵



1.初始化一个边集E,和一个辅助数组vset[]用来判断一条边的2个顶点是否属于同一个集合。



2.然后通过排序算法对边集E排序,选择出最小的权值边。判断选出的边(u,v)是否属于同一集合,判断方法是比较vset[u]和vset[v]的值是否一样。若是一样,则属于同一个集合,不加入MST。若不是则修改所有vset[i] = v的结点让它的值为u ,表示结点u和v所在的集合加入同一集合了。

如:通过堆排序找到了最小权值边(1,3)然后判断vset[1]和vset[3]值是否相同,发现不相同,则加入MST,然后修改vset[3] =vset[1]。执行后表的状态为:



对应的图的状态为:



接下来是边(4,6),它的权值为2。判断发现结点v4,v6不是同一集合,加入MST。修改表格



对应图的状态为:



接下来是(2,5)权值为3,然后加入MST,修改表格



对应图的状态:



接下来是边(3,6),V3和V6也不是同一集合,加入MST。修改表格:



对应图的状态:



接下来是边(1,4)v1和v4属于同一集合,则不加入MST。表格为:



接下来是(2,3) v2和v3不在同一个集合,加入MST,修改表格:



对应图状态为:



到此,所有的结点都在同一集合,MST构建完毕。

 typedef struct{
char vertex[VertexNum]; //顶点表
int edges[VertexNum][VertexNum]; //邻接矩阵,可看做边表
int n,e; //图中当前的顶点数和边数
}MGraph; typedef struct node {
int u; //边的起始顶点
int v; //边的终止顶点
int w; //边的权值
}Edge; void kruskal(MGraph G){
int i,j,u1,v1,sn1,sn2,k;
int vset[VertexNum]; //辅助数组。判定两个顶点是否连通
Edge E[EdgeNum]; //存放全部的边
k=0; //E数组的下标从0開始
//
for (i=0;i<G.n;i++){
for (j=0;j<G.n;j++){
if (G.edges[i][j]!=0 && G.edges[i][j]!=INF){
E[k].u=i;
E[k].v=j;
E[k].w=G.edges[i][j];
k++;
}
}
}
heapsort(E,k,sizeof(E[0])); //堆排序,按权值从小到大排列
for (i=0;i<G.n;i++) { //初始化辅助数
vset[i]=i;
}
k=1; //生成的边数,最后要刚好为总边数
j=0; //E中的下标
while (k<G.n){
sn1=vset[E[j].u];
sn2=vset[E[j].v]; //得到两顶点属于的集合编号
if (sn1!=sn2){ //不在同一集合编号内的话,把边增加最小生成树
printf("%d ---> %d, %d",E[j].u,E[j].v,E[j].w);
k++;
for (i=0;i<G.n;i++){
if (vset[i]==sn2){
vset[i]=sn1;
}
}
}
j++;
}
}

MST(最小生成树)的更多相关文章

  1. MST最小生成树

    首先,贴上一个很好的讲解贴: http://www.wutianqi.com/?p=3012 HDOJ 1233 还是畅通工程 http://acm.hdu.edu.cn/showproblem.ph ...

  2. [BZOJ1937][SHOI2004]Mst最小生成树(KM算法,最大费用流)

    1937: [Shoi2004]Mst 最小生成树 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 802  Solved: 344[Submit][Sta ...

  3. 【BZOJ1937】[Shoi2004]Mst 最小生成树 KM算法(线性规划)

    [BZOJ1937][Shoi2004]Mst 最小生成树 Description Input 第一行为N.M,其中 表示顶点的数目, 表示边的数目.顶点的编号为1.2.3.…….N-1.N.接下来的 ...

  4. [poj1679]The Unique MST(最小生成树)

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 28207   Accepted: 10073 ...

  5. UVA 1151 Buy or Build (MST最小生成树,kruscal,变形)

    题意: 要使n个点之间能够互通,要使两点直接互通需要耗费它们之间的欧几里得距离的平方大小的花费,这说明每两个点都可以使其互通.接着有q个套餐可以选,一旦选了这些套餐,他们所包含的点自动就连起来了,所需 ...

  6. MST最小生成树及克鲁斯卡尔(Kruskal)算法

    最小生成树MST,英文名如何拼写已忘,应该是min spaning tree吧.假设一个无向连通图有n个节点,那么它的生成树就是包括这n个节点的无环连通图,无环即形成树.最小生成树是对边上权重的考虑, ...

  7. MST最小生成树及Prim普鲁姆算法

    MST在前面学习了Kruskal算法,还有一种算法叫做Prim的.这两者的区别是Prim算法适合稠密图,比如说鸟巢这种几乎所有点都有相连的图.其时间复杂度为O(n^2),其时间复杂度与边的数目无关:而 ...

  8. 【KM】BZOJ1937 [Shoi2004]Mst 最小生成树

    这道题拖了好久因为懒,结果1A了,惊讶∑( 口 || [题目大意] 给定一张n个顶点m条边的有权无向图.现要修改各边边权,使得给出n-1条边是这张图的最小生成树,代价为变化量的绝对值.求最小代价之和. ...

  9. Prim求MST最小生成树

    最小生成树即在一个图中用最小权值的边将所有点连接起来.prim算法求MST其实它的主要思路和dijkstra的松弛操作十分相似 prim算法思想:在图中随便找一个点开始这里我们假定起点为“1”,以点1 ...

  10. 【BZOJ2238】Mst 最小生成树+LCA+堆

    [BZOJ2238]Mst Description 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影响,即被删掉的 ...

随机推荐

  1. k8s(00)入门知识介绍

    系列文章说明 本系列文章,可以基本算是 老男孩2019年王硕的K8S周末班课程 笔记,根据视频来看本笔记最好,否则有些地方会看不明白 需要视频可以联系我 k8s概念入门 目录 系列文章说明 k8s概念 ...

  2. 前端练习错题day01

    <1>.css盒子模型中,padding是透明的,这一部分可以显示背景. <2>.注意&&符号左右条件先后顺序,可能会报错. <3>.在 HTML5 ...

  3. 【揭秘】阿里测试框架,各大CTO良心力荐

    自动化测试因其节约成本.提高效率.减少手动干预等优势已经日渐成为测试人员的“潮流”,从业人员日益清楚地明白实现自动化框架是软件自动化项目成功的关键因素之一.本篇文章将从 什么是真正的自动化测试框架.自 ...

  4. 题解 CF576D 【Flights for Regular Customers】

    对每条边来说,可以走这条边的限制解除是按\(d\)的顺序,所以先对每条边按\(d\)排序. 然后考虑每两条边之间的处理,用一个矩阵表示当前走\(d\)步是否可以从一个点到另一个点,称其为状态矩阵,用另 ...

  5. node的async模块

    废话不多说,直接开始 这个模块有几种方法.分别用于的不通的情况自己喜欢怎么用就怎么用 第一个方法,series  这个方法用于串行切无关联.什么意思那就是,里面的方法是一个一个执行的,每一个方法相互不 ...

  6. 【工具】 - BeanUtils增强篇

    public class BeanPlusUtils extends BeanUtils { public static <S, T> List<T> copyListProp ...

  7. dp 数字三角形

    冻龟之前 先看地龟 // // Created by snnnow on 2020/7/23 // //递归算法,除了慢其实还好 #include<iostream> #include&l ...

  8. Python游戏编程入门 中文pdf扫描版|网盘下载内附地址提取码|

    Python是一种解释型.面向对象.动态数据类型的程序设计语言,在游戏开发领域,Python也得到越来越广泛的应用,并由此受到重视. 本书教授用Python开发精彩游戏所需的[]为重要的该你那.本书不 ...

  9. nginx静态资源防盗链

    含义: 用于阻止 Referer 头字段为无效值的请求访问站点.需记住的是,使用适当的 Referer 字段值来伪造请求非常容易,因此本模块的预期目的不是要彻底阻止此类请求,而是阻止常规浏览器发送的大 ...

  10. __name__=='__main__'作用

    .pyw:python源文件,常用语图形界面程序文件.pyc:Python字节码文件 举个例子吧!!先写一个py文件,命名为MyModule.py,里面内容如下: def mymain(): prin ...