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. mysql 联合唯一

    CREATE TABLE `NewTable` ( `id` int NOT NULL , `name` varchar(255) NULL , `phone` varchar(255) NULL , ...

  2. 一个startforresult的例子

    https://blog.csdn.net/qq_32521313/article/details/52451364

  3. Shell变量的作用域:Shell全局变量、环境变量和局部变量

    Shell 变量的作用域(Scope),就是 Shell 变量的有效范围(可以使用的范围). 在不同的作用域中,同名的变量不会相互干涉,就好像 A 班有个叫小明的同学,B 班也有个叫小明的同学,虽然他 ...

  4. Aliyun Linux2安装Docker

    安装教程 使用手册

  5. 进度条函数 -------ajax初试

    做一个显示任务完成情况的进度条: <!DOCTYPE html> <html> <head> <meta charset="utf-8"& ...

  6. 可能会用的到的JQ插件

    ├─lib │ jquery jQuery类库(v1.9.1) │ bootstrapSwitch 开关控件 │ Hui-iconfont_v1.0 阿里图标字体库(H-ui定制) │ font-aw ...

  7. Python os.chmod() 方法

    概述 os.chmod() 方法用于更改文件或目录的权限.高佣联盟 www.cgewang.com 语法 chmod()方法语法格式如下: os.chmod(path, mode) 参数 path - ...

  8. PHP floor() 函数

    实例 向下舍入为最接近的整数: <?phpecho(floor(0.60) . "<br>");echo(floor(0.40) . "<br&g ...

  9. 2019 HL SC day4

    自闭场本来 以为 顶多一些不太会 结果发现 一堆不太会 . 树状数组  感觉 好久没看 了有点遗忘 不过还好 现在我来了.莅临之神将会消灭一切知识点哦. 今天说点不一样东西 树状数组 hh 很有用的东 ...

  10. CF 题目选做

    写省选的题目对noip没什么大用 关键是 细节题或者是思考题比较重要 练思维自然是CF比较好了 把我见到的比较好的CF题放上来刷一刷. LINK:Complete the projects 就是说一个 ...