最小生成树prim算法实现

 

‘      ’最小生成树,就是权值(两点间直线的值)之和的最小值。

首先,要用二维数组记录点和权值。如上图所示无向图:

int G[6][6];
       G[1][2]= G[2][1]=4;
       G[1][3]= G[3][1]=2;
       ......

然后再求最小生成树。具体方法是:

1.先选取一个点作起始点,然后选择它邻近的权值最小的点(如果有多个与其相连的相同最小权值的点,随便选取一个)。如1作为起点。

使用全局变量来用做标记      visited[1]=1;

pos=1;

//用low[]数组不断刷新最小权值,low[i](0<i<=点数)的值为:i点到邻近点(未被标记)的最小距离。

low[1]=0;  //起始点i到邻近点的最小距离为0

low[2]=map[pos][2]=4;

low[3]=map[pos][3]=2;

low[4]==map[pos][4]=3;

low[5]=map[pos][5]=MaxInt;  //无法直达

low[6]=map[pos][6]=MaxInt;

2.再在伸延的点找与它邻近的两者权值最小的点。

//low[]以3作当前位置进行更新

visited[3]=1;

pos=3;

low[1]=0;                                                //已标记,不更新

low[2]=map[1][2]=4;                               //比5小,不更新

low[3]=2;                                                //已标记,不更新

low[4]=map[1][4]=3;                             //比1大,更新后为:low[4]=map[3][4]=1;

low[5]=map[1][5]=MaxInt;                       //无法直达,不更新

low[6]=map[1][6]=MaxInt;                     //比2大,更新后为:low[6]=map[3][6]=2;

-----------------------------------------------------------------------------------------------------------------------------------------------

是最小值而又没有被标记的为low[4]

visited[4]=1;

pos=4;

low[1]=0;                                       //已标记不更新

low[2]=map[1][2]=4;                      //map[4][2] == 4 一样大不更新

low[3]=2;                                     //已标记不更新

low[4]=map[1][4]=1;                     //已标记不更新

low[5]=map[4][5]=6;                     //比max小更新

low[6]=map[4][6]=2;                      //和map[3][6]一样大不更新

-------------------------------------------------------------------------------------------------------------------------------------------------

是最小值而又没有被标记的为low[6]

visited[2]=1;

pos=4;

low[1]=0;                                       //已标记不更新

low[2]=map[1][2]=4;                      //已标记不更新

low[3]=2;                                     //已标记不更新

low[4]=map[1][4]=1;                     //已标记不更新

low[5]=map[6][5]=4;                     //比map[4][5]小更新为3

low[6]=map[4][6]=2;                      //已标记不更新

--------------------------------------------------------------------------------------------------------------------------------------

是最小值而又没有被标记的为low[2]

visited[4]=1;

pos=4;

low[1]=0;                                       //已标记不更新

low[2]=map[1][2]=4;                      //比它大不更新

low[3]=2;                                     //已标记不更新

low[4]=map[1][4]=1;                     //已标记不更新

low[5]=map[2][5]=3;                     //比他小更新

low[6]=map[4][6]=2;                      //已标记不更新

----------------------------------------------------------------------------------------------------------------------------------------------

是最小值而又没有被标记的为low[5]

visited[4]=1;

pos=4;

low[1]=0;                                       //已标记不更新

low[2]=map[1][2]=4;                      //已标记不更新

low[3]=2;                                     //已标记不更新

low[4]=map[1][4]=1;                     //已标记不更新

low[5]=map[6][5]=4;                     //已标记不更新

low[6]=map[4][6]=2;                      //已标记不更新

------------------------------------------------------------------------------------------------------------------------------------------------

3.如此类推...

 
     当所有点都连同后,结果最生成树如上图所示。

所有权值相加就是最小生成树,其值为2+1+2+4+3=12。

--------------------------------------------------------------------------------------------------------------------------------------------

#include <cstdio>
#include <cstdlib>
//#define _OJ_
#define max 999
int visit[100]; typedef struct Graph1
{
int nv;
int ne;
int G[100][100];
} Graph1, *Graph; int
prim_Graph(Graph g)
{
int i, j, i1, pos, result, min;
int low[100];
visit[1] = 1; low[1] = 0; result = 0; pos = 1;//从第一个开始
for(i = 2;i <= g->nv; i++) {
low[i] = g->G[pos][i]; printf("low%d == %d ", i, low[i]);} printf("\n"); for(i = 1;i < g->nv; i++) {
min = max;
for(j = 1;j <= g->nv; j++) {
if(visit[j] == 0 && min > low[j]) {
min = low[j]; pos = j;
}
} result += min;
visit[pos] = 1;
printf("pos == %d ", pos);
for(i1 = 1;i1 <= g->nv; i1++) {
if(visit[i1] == 0 && low[i1] > g->G[pos][i1])
low[i1] = g->G[pos][i1]; //把没有访问过的与pos相邻的且权
//重比原来小的就更改,否则保持原来最小的值
printf("low%d == %d ", i1, low[i1]);
}
printf("\n");
}
return result;
} int main(int argc, char const *argv[]) {
#ifndef _OJ_ //ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif int i, j, v1, v2, weight, result;
Graph g;
g = (Graph) malloc (sizeof(Graph1));
scanf("%d %d", &g->nv, &g->ne);
for(i = 1;i <= g->nv; i++) {
for(j = 1;j <= g->nv; j++) {
g->G[i][j] = max; //初始值赋最大
}
} for(i = 1;i <= g->ne; i++) {
scanf("%d %d %d", &v1, &v2, &weight);
g->G[v1][v2] = weight; g->G[v2][v1] = weight;//建立无向图
}
for(i = 1;i <= g->nv; i++)
visit[i] = 0; //标记初始化为零 result = prim_Graph(g);
printf("%d\n", result); return 0;
}

  ------------------------------------------------------------------------------------------------------------------------------------------

low2 == 4 low3 == 2 low4 == 3 low5 == 999 low6 == 999
pos == 3 low1 == 0 low2 == 4 low3 == 2 low4 == 1 low5 == 999 low6 == 2
pos == 4 low1 == 0 low2 == 4 low3 == 2 low4 == 1 low5 == 6 low6 == 2
pos == 6 low1 == 0 low2 == 4 low3 == 2 low4 == 1 low5 == 4 low6 == 2
pos == 2 low1 == 0 low2 == 4 low3 == 2 low4 == 1 low5 == 3 low6 == 2
pos == 5 low1 == 0 low2 == 4 low3 == 2 low4 == 1 low5 == 3 low6 == 2
12

-----------------------------------------------------------------------------------------------------------------------------------------------

总而言之每一个low[]数组存入一个最小的权值,   如果遇到更小的便换为更小的;

low[1]---v1

low[2]----v2

------------------

类似于在线处理,, 总保存最小的那一个;;;

生成最小树prim算法的更多相关文章

  1. 最小生成树与Prim算法

    最小生成树(MST) 定义 首先是一棵树(废话 其次没有回路(废话 包含全部顶点和V-1条边 边的权重和最小!!!!! 所以如果是单棵最小生成树,至少说明图是连通的.不然就是森林. 生成思路 既然是根 ...

  2. 最小生成二叉树-prim算法

    1.prim算法:一种计算生成最小生成树的方法,它的每一步都会为一棵生长中的树添加一条边. 2.时间复杂度:

  3. Prim算法生成迷宫

    初始化地图 function initMaze(r,c){ let row = new Array(2 * r + 1) for(let i = 0; i < row.length; i++){ ...

  4. Prim算法(三)之 Java详解

    前面分别通过C和C++实现了普里姆,本文介绍普里姆的Java实现. 目录 1. 普里姆算法介绍 2. 普里姆算法图解 3. 普里姆算法的代码说明 4. 普里姆算法的源码 转载请注明出处:http:// ...

  5. Prim算法(二)之 C++详解

    本章是普里姆算法的C++实现. 目录 1. 普里姆算法介绍 2. 普里姆算法图解 3. 普里姆算法的代码说明 4. 普里姆算法的源码 转载请注明出处:http://www.cnblogs.com/sk ...

  6. Prim算法(一)之 C语言详解

    本章介绍普里姆算法.和以往一样,本文会先对普里姆算法的理论论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 普里姆算法介绍 2. 普里姆算法图解 3. 普里 ...

  7. 算法之prim算法

    最小生成树是数据结构中图的一种重要应用,它的要求是从一个带权无向完全图中选择n-1条边并使这个图仍然连通(也即得到了一棵生成树),同时还要考虑使树的权最小. prim算法就是一种最小生成树算法. 普里 ...

  8. Kruskal和Prim算法求最小生成树

    Kruskal算法求最小生成树 测试数据: 5 6 0 1 5 0 2 3 1 2 4 2 4 2 2 3 1 1 4 1 输出: 2 3 1 1 4 1 2 4 2 0 2 3 思路:在保证不产生回 ...

  9. Prim算法堆优化

    #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> ...

随机推荐

  1. C# 简单邮件群发通用类

    public static class Email { /// <summary> /// 发件人 /// </summary> public static string ma ...

  2. ASP.NET MVC 4框架揭秘(微软6任MVP,高级软件顾问蒋金楠新作)

    http://www.cnblogs.com/artech/

  3. C语言中关于float和double的输入输出格式

    1.对于double类型,输入格式为scanf("%lf %lf", &foo, &bar); 对于float类型,输入格式为scanf("%f %f, ...

  4. Chromium浏览器高级开发系列第一篇:如何获取最新chromium源码

    背景:     最近摊上一个事儿,领导非要让写一篇技术文章,思来想去,自己接触chrome浏览器时间也不短了,干脆就总结一下吧.于是乎,本文顺理成章.由于有些细节必需描述清楚,所以这次先讲如何拿到ch ...

  5. struts2<s:property />标签

    struts2的<property />标签是输出标签 其value属性是指定输出的内容,如果value属性没有写出来,则默认输出对象栈栈顶的元素. 例如,我们在对象栈中添加一个Perso ...

  6. Java--CJDP

    was定义,包定义, 1. Java的接口概念 进行封装,方便的使用 2. 包定义,Java 中多种包,进行迁移使用,包的导入,例如对数据库的操作Hibernate 3. 配置文件xml和json,对 ...

  7. MySQL数据库下用户及用户权限配置

    问题:使用某大腿写的远程工具管理Mysql数据库时发现所有数据能正常显示,但是无法进行删除.修改等操作. 思路:可以远程读取到数据库里的信息,说明当前主机可以远程连接数据库.却无法进行删除.修改这些操 ...

  8. JS input文本框禁用右键和复制粘贴功能的代码

    代码如下: function click(e) { if (document.all) { ||||) { oncontextmenu='return false'; } } if (document ...

  9. java 反射的踩的一个坑

    今天工作的时候用到了一个反射.其业务简单描述为:系统启动时将需要定时调用的方法签名保存到数据库中,开启线程定时从数据库中读取对应的方法签名,通过反射生成实例后调用方法.完成一定的定时任务. 写到的方法 ...

  10. JS获取图片实际宽高及根据图片大小进行自适应

    JS获取图片实际宽高,以及根据图片大小进行自适应  <img src="http://xxx.jpg" id="imgs" onload="ad ...