文章目录

  • 1.概念
  • 2.构造最小生成树Prim算法
  • 3.构造最小生成树Kruskal算法

1.概念

  • 对图运用不同的遍历方法就可能得到图的不同遍历顺序,每一种遍历顺序对应于一棵生成树
  • 对于无向连通图,所有的生成树中必有一棵树的所有边的权的总和最小的,称之为最小生成树(Minimum cost spanning tree)

练习题:
LeetCode 1135. 最低成本联通所有城市(最小生成树+排序+并查集)
LeetCode 1489. 找到最小生成树里的关键边和伪关键边(并查集+kruskal最小生成树)

2.构造最小生成树Prim算法

从某点出发(该点加入集合U),找到跟它相连接的点,从中取出权值最小的,加入集合U,对这个集合U,查找与U内所有的点相连的点的权值,取权值最小的点,加入集合U,直到所有点加入到U。

struct CloseEdge    //最短的边
{int startV;int endV;int minWeight;  //最小的权值bool operator < (const CloseEdge &s) const{//符号重载return minWeight < s.minWeight;}
};
//----------prim最小生成树---------------
void MiniSpanTree_Prim(char ch)
{int s = findPos(ch);if(s >= v)return;cout << "从 " << ch << " 开始的Prim最小生成树:" << endl;int i, j, k, x, w, minid, sum = 0;for(i = 0; i < v; ++i)visited[i] = 0;//访问标志置0visited[s] = 1;vector<int> q;vector<int>::iterator it;q.push_back(s);for(i = 0; i < v-1; ++i){for(it = q.begin(),x = 0; it != q.end(); ++it,++x){w = MaxValue;for(j = 0; j < v; ++j){if (!visited[j] && ew[*it][j] < w){w = ew[*it][j];minid = j;//记录较小的权的序号为k}}close_edge[x].minWeight = w;close_edge[x].startV = *it;close_edge[x].endV = minid;}sort(close_edge,close_edge+x);visited[close_edge[0].endV] = 1;cout << vertex[close_edge[0].startV] << "-" << vertex[close_edge[0].endV] << " 权值 " << close_edge[0].minWeight << endl;sum += close_edge[0].minWeight;q.push_back(close_edge[0].endV);}cout << "最小生成树权重总和为:" << sum << endl;}

我这个程序比较好理解,但是复杂度n3。书上的程序写法是n2

int main()
{//------------以下测试Prim最小生成树------------------
//    A -40- B -50- C
//  30|  \10 5|    20|
//    D -35- E -45- F
//  10|    55|    10|
//    I -15- G -25- H
//请输入以下数据生成上面的图
//A B C D E F G H I  A B 40 B C 50 A D 30 B E 5 C F 20 D E 35 E F 45 E G 55 F H 10 G H 25 A E 10 D I 10 I G 15arrGraph bg(9,13);    //9个顶点,13条边,默认生成无向图bg.creatGraph();bg.printArrOfGraph();bg.MiniSpanTree_Prim('A');bg.MiniSpanTree_Prim('I');//从任一点出发,最小花费都一样return 0;
}

完整代码:https://github.com/hitskyer/course/blob/master/dataAlgorithm/chenmingming/graph/arrayGraph.cpp


从任意一点出发最小生成树的最小代价总和都相等。

看了别人的代码,调试后,明白了n2复杂度的Prim算法

void MiniSpanTree_Prim_O_n2(char ch)
{int s = findPos(ch);if (s >= v)return;cout << "从 " << ch << " 开始的Prim最小生成树:" << endl;int i, j, k, minweight, sum = 0;int adjvex[v];  //保存顶点下标int lowcost[v]; //保存相关顶点见的权值lowcost[s] = 0; //=0,加入了生成树adjvex[s] = s;  //起点下标为自己for(i = 0; i < v; ++i){if(i == s)continue;lowcost[i] = ew[s][i];//将s起点与其他点的权值初始化adjvex[i] = s;//到达i的前一个点初始化为起点}for(i = 0; i < v-1; ++i){minweight = MaxValue;for(j = 0, k = 0; j < v; ++j){if(lowcost[j] != 0 && lowcost[j] < minweight)//未加入生成树的,且j点的比较小{minweight = lowcost[j];//更新最小值k = j;//下标记录入k}}cout << vertex[adjvex[k]] << "-" << vertex[k] << " 权值 " << ew[adjvex[k]][k] << endl;lowcost[k] = 0;//最小的权值点k加入生成树sum += ew[adjvex[k]][k];for(j = 0; j < v; ++j){if(lowcost[j] != 0 && ew[k][j] < lowcost[j])//k加入生成树后,对k周围的权与最小权lowcost比较{lowcost[j] = ew[k][j];//更小的权更新lowcost数组adjvex[j] = k;//并记录j的前一位是k}}}cout << "最小生成树权重总和为:" << sum << endl;
}

3.构造最小生成树Kruskal算法

该算法思路是从边(权重)出发考虑,取最小的权出来,若该边不会造成回路就加入生成树,然后次最小,循环下去

//----------Kruskal最小生成树---------------
void MiniSpanTree_Kruskal()
{cout << "Kruskal最小生成树:" << endl;int i, j, k = 0, sum = 0;CloseEdge edges[MaxEdgeNum];    //边数据集for(i = 0; i < v; ++i)  //把边信息输入到edges数组for(j = 0; j < v; ++j)if(ew[i][j] != MaxValue && i > j)//无向图,i>j 矩阵中一半就可获取全部信息{edges[k].startV = i;edges[k].endV = j;edges[k].minWeight = ew[i][j];k++;}sort(edges,edges+k);//边排序int parent[e];             //作用,判断边与边是否形成回路int vf1, vf2;for(i = 0; i < k; ++i)parent[i] = 0;for(i = 0; i < k; ++i){vf1 = Find(parent, edges[i].startV);vf2 = Find(parent, edges[i].endV);if(vf1 != vf2)//没有回路,可以选入生成树{parent[vf2] = vf1;cout << vertex[edges[i].startV] << "-" << vertex[edges[i].endV]<< " 权重 " << edges[i].minWeight << endl;sum += edges[i].minWeight;}}cout << "最小生成树权重总和为:" << sum << endl;
}
int Find(int* parent, int v)
{int t = v;while(parent[t] > 0)t = parent[t];return t;
}

图Graph--最小生成树相关推荐

  1. C++编程练习(10)----“图的最小生成树“(Prim算法、Kruskal算法)

    1.Prim 算法 以某顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树. 2.Kruskal 算法 直接寻找最小权值的边来构建最小生成树. 比较: Kruskal 算法主要是针对边来展开,边数 ...

  2. 数据结构--图(Graph)详解(四)

    数据结构–图(Graph)详解(四) 文章目录 数据结构--图(Graph)详解(四) 一.图中几个NB的算法 1.普里姆算法(Prim算法)求最小生成树 2.克鲁斯卡尔算法(Kruskal算法)求最 ...

  3. 数据结构--图(Graph)详解(三)

    数据结构–图(Graph)详解(三) 文章目录 数据结构--图(Graph)详解(三) 一.深度优先生成树和广度优先生成树 1.铺垫 2.非连通图的生成森林 3.深度优先生成森林 4.广度优先生成森林 ...

  4. 数据结构与算法(python):图(Graph)的基本概念及应用

    参考自 MOOC数据结构与算法Python版 本章代码: https://github.com/HuiFang-hub/-/tree/main. 目录 一.图Graph的概念 1.1 互联网 1.2 ...

  5. 算法:通过普利姆(Prim)算法,求出图的最小生成树

    请看如下的示例图,该图有 V1-V7 七个顶点,每个顶点之间的距离如图所示: 如果上面的图为七个城市的地理分布图,城市间相连的边上的数字为城市间的距离.我们要在这七个城市里面架设电线,使得每一个城市都 ...

  6. 从图(Graph)到图卷积(Graph Convolution):漫谈图 神经⽹络模型 (⼀)

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 作者最近看了一些图与图卷积神经网络的论文,深感其强大,但一些Sur ...

  7. 算法导论之图的最小生成树

    引出最小生成树,是提到电子线路设计时,要把数个元件的引脚连接在一起,使其电位相同.使n个引脚互相连通,可以使用n-1条连接线,每条连接线连接两个引脚.寻求连接线最少的方案,是最小生成树的应用.将电子线 ...

  8. 数据结构--图(Graph)详解(二)

    数据结构–图(Graph)详解(二) 文章目录 数据结构--图(Graph)详解(二) 一.图的存储结构 1.图的顺序存储法 2.图的邻接表存储法 3.图的十字链表存储法 4.图的邻接多重表存储法 二 ...

  9. 数据结构--图(Graph)详解(一)

    数据结构–图(Graph)详解(一) 文章目录 数据结构--图(Graph)详解(一) 一.图的基本概念 1.图的分类 2.弧头和弧尾 3.入度和出度 4.(V1,V2) 和 < V1,V2 & ...

  10. python加载模型文件进行图片分类_tensorflow通过模型文件,使用tensorboard查看其模型图Graph方式...

    Google提供了一个工具,TensorBoard,它能以图表的方式分析你在训练过程中汇总的各种数据,其中包括Graph结构. 所以我们可以简单的写几行Pyhton,加载Graph,只在logdir里 ...

最新文章

  1. C++/C++11中头文件algorithm的使用
  2. 网易有毛病,我的账号被锁了,去解锁时候又几把提示不成功,浪费劳资感情啊
  3. checkbox 与文字对齐
  4. PHP array_combine()
  5. c++基础语句(条件判断)
  6. ForkJoin框架简单使用
  7. 百度推出海外版网盘:竟免费不限速
  8. python闭合函数_Python中函数的闭包
  9. 解决办法:为什么我的DLL中加载后找不到指定的函数
  10. ZStack 3.1 私有云率先支持IPv6 持续深耕精细化云平台
  11. 计算机实验报告protel,Protel99se实验报告.doc
  12. Mac不用Boot Camp 安装双系统
  13. pytorch双线性插值
  14. [VS code - SSH Remote] ln: failed to create hard link ... File exists
  15. Thoughtworks笔试
  16. lte tm模式_请教大家个问题,LTE传输模式TM1-TM8中哪种属于MIM.. - 通信技术你问我答 - 纯技术讨论者的天地 - Powered by C114...
  17. 第17章 其他数据库日志【4.日志与备份篇】【MySQL高级】
  18. 记一次搜狐畅游后台开发笔试
  19. 支付业务与技术架构学习总结(7)——从金融牌照(三方支付牌照),看互联网巨头的金融布局
  20. 软件架构场景之—— BFF:如何处理好微服务之间千丝万缕的关系?

热门文章

  1. 上传SVN丢失.a文件的问题
  2. 简单的深度优先遍历和广度优先遍历
  3. lightoj1259 线性筛的另一种写法 v变成bool标记数组
  4. 安装rlwrap 的简单方法
  5. java基础----Java中枚举的使用(一)
  6. IEnumerable和IQueryable的区别
  7. linux查看磁盘占用
  8. javascript自定义startWith()和endWith()方法
  9. vbs调用WebService -- 使用xmlhttp
  10. Redis基数统计之HyperLogLog小内存大用处