最小生成树,普利姆算法.

简述算法:

  先初始化一棵只有一个顶点的树,以这一顶点开始,找到它的最小权值,将这条边上的令一个顶点添加到树中

  再从这棵树中的所有顶点中找到一个最小权值(而且权值的另一顶点不属于这棵树)

  重复上一步.直到所有顶点并入树中.

图示:

注:以a点开始,最小权值为1,另一顶点是c,将c加入到最小生成树中.树中 a-c

在最小生成树中的顶点找到一个权值最小且另一顶点不在树中的,最小权值是4,另一个顶点是f,将f并入树中, a-c-f

重复上一步骤,a-c-f-d, a-c-f-d-b, a-c-f-d-b-e.

邻接矩阵的实现

我又构建了一个邻接矩阵(prim_tree),将我们求出的最小生成树写入其中.

我们还需要一个visited数组,来确定一个顶点是否已被纳入最小生成树中.

1)初始化,visited数组,prim_tree节点信息,矩阵.1-11,41-55行

2)将一个顶点并入树(prim_tree)中.以这个顶点开始,进行遍历寻找最小权值.

  这里用了三层循环嵌套.

    i这一层的作用是遍历图的节点信息,我们要将所有节点都纳入树中.

    j这一层的作用是遍历树的节点信息.(我们是通过visited数组来确定一个节点是否属于最小生成树的,19行,if的作用)

    k这一层的作用是在j节点所在所在矩阵的行中找到最小权值.

 (注:j和k配合,找到树中的最小权值(最小权值的另一个节点没有被纳入树中,23行if的作用).j查找的节点信息的下标,但矩阵是正方形的,所以j既是节点信息的下标,又是该节点在矩阵中的列位置.而k则在j这一列查找最小权值.当j将树遍历一遍,这时会找到一个最小权值,这个最小权值的另一个顶点就是我们将要纳入树中的节点.)

3)将上面获得的信息写入树中.(写入时也要判断该节点是否已被纳入树中.没有纳入树中的节点才会将其纳入树中.)

  1. //最小生成树prim算法
  2. static void init_prim(Graph * graph, Graph * prim_tree);
  3. void Prim(Graph * graph, Graph * prim_tree)
  4. {
  5. bool visited[graph->vertexs];
  6. int i, j, k, h;
  7. int power, power_j, power_k;
  8.  
  9. for ( i = ; i < graph->vertexs; i++ )
  10. visited[i] = false;
  11. init_prim(graph, prim_tree);
  12.  
  13. visited[] = true;
  14. for ( i = ; i < graph->vertexs; i++ )
  15. {
  16. power = MAX_VALUE;
  17. for ( j = ; j < graph->vertexs; j++ )
  18. {
  19. if ( visited[j] )
  20. {
  21. for ( k = ; k < graph->vertexs; k++ )
  22. {
  23. if ( power > graph->arcs[j][k] && !visited[k] )
  24. {
  25. power = graph->arcs[j][k];
  26. power_j = j;
  27. power_k = k;
  28. }
  29. }
  30. }
  31. }
  32. //min power
  33. if ( !visited[power_k] )
  34. {
  35. visited[power_k] = true;
  36. prim_tree->arcs[power_j][power_k] = power;
  37. }
  38. }
  39. }
  40.  
  41. static void init_prim(Graph * graph, Graph * prim_tree)
  42. {
  43. int i, j;
  44.  
  45. prim_tree->vertexs = graph->vertexs;
  46. for ( i = ; i < prim_tree->vertexs; i++ )//初始化节点
  47. prim_tree->vertex[i] = graph->vertex[i];
  48. for ( i = ; i < prim_tree->vertexs; i++ )//初始化矩阵
  49. {
  50. for ( j = ; j < prim_tree->vertexs; j++ )
  51. {
  52. prim_tree->arcs[i][j] = MAX_VALUE;
  53. }
  54. }
  55. }

上述代码适用于连通图.

如果想运行这个程序,到http://www.cnblogs.com/ITgaozy/p/5187483.html找源码,将上面的代码粘到里面就可以了.

邻接表的实现

算法和矩阵一样,只是由于数据结构不同,在代码上有些差别.

  1. static void init_prim(Graph * graph, Graph * prim_tree);
  2. void g_prim(Graph * graph, Graph * prim_tree)
  3. {
  4. bool visited[graph->vertexs];
  5. int i, j, k;
  6. int power, pos;
  7. Arc_node * tmp;
  8.  
  9. for ( i = ; i < graph->vertexs; i++ )
  10. visited[i] = false;
  11. init_prim(graph, prim_tree);
  12.  
  13. visited[] = true;
  14. for ( i = ; i < graph->vertexs; i++ )
  15. {
  16. power = INT_MAX;//limits.h
  17. for ( j = ; j < graph->vertexs; j++ )
  18. {
  19. if ( visited[j] )
  20. {
  21. tmp = graph->adjlist[j].next;
  22. while ( tmp != NULL )
  23. {
  24. if ( power > tmp->distance && !visited[tmp->pos] )
  25. {
  26. power = tmp->distance;
  27. pos = tmp->pos;
  28. k = j;
  29. }
  30. tmp = tmp->next;
  31. }
  32. }
  33. }
  34. if ( !visited[pos] )
  35. {
  36. if ( prim_tree->adjlist[k].next == NULL )
  37. {
  38. prim_tree->adjlist[k].next = make_node(pos, power);
  39. }
  40. else
  41. {
  42. tmp = prim_tree->adjlist[k].next;
  43. while ( tmp->next != NULL )
  44. tmp = tmp->next;
  45. tmp->next = make_node(pos, power);
  46. }
  47. visited[pos] = true;
  48. }
  49. }
  50. }
  51.  
  52. static void init_prim(Graph * graph, Graph * prim_tree)
  53. {
  54. int i;
  55.  
  56. for ( i = ; i < graph->vertexs; i++ )
  57. {
  58. prim_tree->adjlist[i].info = graph->adjlist[i].info;
  59. prim_tree->adjlist[i].next = NULL;
  60. }
  61. prim_tree->vertexs = graph->vertexs;
  62. }

到http://www.cnblogs.com/ITgaozy/p/5187526.html里找到源码,将上述代码粘到源码中,就可以了.

由于本人水平有限,不足之处还望大家不吝指教.

最小生成树Prim算法(邻接矩阵和邻接表)的更多相关文章

  1. hdoj 2063 过山车【匈牙利算法+邻接矩阵or邻接表】

    过山车 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  2. 数据结构代码整理(线性表,栈,队列,串,二叉树,图的建立和遍历stl,最小生成树prim算法)。。持续更新中。。。

    //归并排序递归方法实现 #include <iostream> #include <cstdio> using namespace std; #define maxn 100 ...

  3. 图论算法(五)最小生成树Prim算法

    最小生成树\(Prim\)算法 我们通常求最小生成树有两种常见的算法--\(Prim\)和\(Kruskal\)算法,今天先总结最小生成树概念和比较简单的\(Prim\)算法 Part 1:最小生成树 ...

  4. SWUST OJ 1075 求最小生成树(Prim算法)

    求最小生成树(Prim算法) 我对提示代码做了简要分析,提示代码大致写了以下几个内容 给了几个基础的工具,邻接表记录图的一个的结构体,记录Prim算法中最近的边的结构体,记录目标边的结构体(始末点,值 ...

  5. 最小生成树,Prim算法与Kruskal算法,408方向,思路与实现分析

    最小生成树,Prim算法与Kruskal算法,408方向,思路与实现分析 最小生成树,老生常谈了,生活中也总会有各种各样的问题,在这里,我来带你一起分析一下这个算法的思路与实现的方式吧~~ 在考研中呢 ...

  6. PAT1013. Battle Over Cities(邻接矩阵、邻接表分别dfs)

    //采用不同的图存储结构结构邻接矩阵.邻接表分别dfs,我想我是寂寞了吧,应该试试并查集,看见可以用并查集的就用dfs,bfs代替......怕了并查集了 //邻接矩阵dfs #include< ...

  7. 图的存储结构:邻接矩阵(邻接表)&链式前向星

    [概念]疏松图&稠密图: 疏松图指,点连接的边不多的图,反之(点连接的边多)则为稠密图. Tips:邻接矩阵与邻接表相比,疏松图多用邻接表,稠密图多用邻接矩阵. 邻接矩阵: 开一个二维数组gr ...

  8. 最小生成树—prim算法

    最小生成树prim算法实现 所谓生成树,就是n个点之间连成n-1条边的图形.而最小生成树,就是权值(两点间直线的值)之和的最小值. 首先,要用二维数组记录点和权值.如上图所示无向图: int map[ ...

  9. Highways POJ-1751 最小生成树 Prim算法

    Highways POJ-1751 最小生成树 Prim算法 题意 有一个N个城市M条路的无向图,给你N个城市的坐标,然后现在该无向图已经有M条边了,问你还需要添加总长为多少的边能使得该无向图连通.输 ...

随机推荐

  1. python use dom to write xml file

    #encoding:utf-8 ''' write xml in dom style ''' from xml.dom.minidom import Document doc = Document() ...

  2. 日暮·第二章·烽烟传讯

    第二章 烽烟传讯   夜幕降临,整个泉州府更见喧闹,那些个白日里将养了一日的花红柳绿再也耐不住寂寞,招招摇摇着在人来人往的主街上舒展着自己的风情,妖妖娆娆地换却春风一度.    城东的招福客栈在经过了 ...

  3. 如何改变Activity在当前任务堆栈中的顺序,Intent参数大全

    引用:http://blog.csdn.net/think_soft/article/details/7477072 本示例演示如何通过设置Intent对象的标记,来改变当前任务堆栈中既存的Activ ...

  4. Xcode报错:“Your build settings specify a provisioning profile with the UUID..... however, no such provisioning profile was found”

    运行环境: Xcode5 & 5.0及以上版本 对工程进行Archive打包的时候出现如下错误   问题描述: Code Sign error: No matching provisionin ...

  5. C# vs MySql

    MySqlHelper类 /// <summary> ///MySql操作类 /// </summary> public abstract class MySqlHelper ...

  6. keil l251 command summary --Lib

    keil l251 command summaryLIB251 LIST MYLIB.LIB TO MYLIB.LST PUBLICS LIB251 EXTRACT MYLIB.LIB (GOODCO ...

  7. Ajax实现提交表单时验证码自动验证(原创自Zjmainstay)

    本文通过源码展示如何实现表单提交前,验证码先检测正确性,不正确则不提交表单,更新验证码. 1.前端代码 index.html <!DOCTYPE html> <html> &l ...

  8. debian+apache+acme_tiny+lets-encrypt配置笔记

    需要预先将需要申请ssl的域名指向到服务器,此方法完全通过api实现,好处是绿色无污染,不需要注册账号,不会泄露私人信息环境为 debian7+apache apt-get install apach ...

  9. js最新手机号码、电话号码正则表达式

    原文链接:http://caibaojian.com/regexp-example.html 正则表达式(regular expression)是一个描述字符模式的对象.使用javascript正则表 ...

  10. 基于MSP430F413水果电池供电的低功耗时钟

      我最早接触MSP430时候,看到书的第一页就是一张水果电池的图片,一直以来想做一个低功耗的可以水果电池供电的系统,毕业之后的下半年选择MSP430F413单片机来画了一个低功耗的板子,一直没有调试 ...