图Graph--最小生成树

文章目录

    • 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;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/480234.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Longformer:超越RoBERTa,为长文档而生的预训练模型

星标/置顶小屋&#xff0c;带你解锁最萌最前沿的NLP、搜索与推荐技术文 | ChrisCao, 小轶前言今天要与大家分享的是AllenAI今年发表的最新工作&#xff0c;Longformer——一种可高效处理长文本的升级版Transformer。作者团队提供了开源代码&#xff0c;大家可快速复现&#xff…

工程实践:基于规则句法的事件关系与主谓宾三元组抽取项目实现

目前&#xff0c;知识图谱在学术界如火如荼地进行&#xff0c;但受限于知识图谱各个环节中的性能问题&#xff0c;还尚未能够在工业界大规模运用。而与知识图谱中以实体为知识节点&#xff0c;实体关系为实体关系边对知识进行组织不同&#xff0c;以事件作为节点&#xff0c;事…

论文浅尝 | LightRNN:存储和计算高效的 RNN

链接&#xff1a;https://arxiv.org/pdf/1610.09893.pdf动机在NLP任务中使用RNN已经被证明是很有用的模型方法。但是传统的RNN在NLP中的应用有一个很大的限制&#xff1a;RNN的输出输入Embedding占用的空间太大&#xff0c;比如1024维10M词表大小的Embedding矩阵就要占掉40GB&a…

阿里最全Java面试100题汇总:涵盖天猫、蚂蚁金服等面试题!含答案~

【阿里天猫、蚂蚁、钉钉面试题目】 1、微信红包怎么实现。 2、海量数据分析。 3、测试职位问的线程安全和非线程安全。 4、HTTP2.0、thrift。 5、面试电话沟通可能先让自我介绍。 6、分布式事务一致性。 7、nio的底层实现。 8、jvm基础是必问的&#xff0c;jvm GC原理&a…

ACL2020 奇葩论文标题大赏

星标/置顶小屋&#xff0c;带你解锁最萌最前沿的NLP、搜索与推荐技术文 | 灵魂写手rumor酱编 | 不拖更的夕小瑶又是一年一度的ACL&#xff0c;之前通过卖萌屋Arxiv服务已经零零碎碎看了一些&#xff0c;还是准备刷一下论文list&#xff0c;看看哪篇能让我的模型效果一飞冲天。…

字符串匹配算法(BF RK)

文章目录1. BF&#xff08;Brute Force&#xff09;暴力匹配BF代码2. RK&#xff08;Rabin-Karp&#xff09;算法RK代码3. 思考题&#xff1a;&#xff08;二维匹配&#xff09;1. BF&#xff08;Brute Force&#xff09;暴力匹配 BF算法的思想&#xff0c;在主串中&#xff0…

用Python寻找最优投资组合

原文地址&#xff1a;https://www.jianshu.com/p/2a25dfd465e9 现代投资组合理论&#xff08;Modern Portfolio Theory&#xff0c;MPT&#xff09;告诉我们投资者应该分散投资来实现最小化风险最大化投资回报。大邓刚开始学习这方面知识&#xff0c;用了将近一天的时候才搞懂M…

技术动态 | 事理图谱,下一代知识图谱

本文转载自公众号&#xff1a;DataHorizon。 人工智能与认知智能当前人工智能时代下&#xff0c;机器与人类之间的博弈一直在进行着。如图1所示&#xff0c;从1926年达特茅斯会议的召开标志人工智能诞生到深度学习模型在…

头条Java后台3面(含答案):事务+List集合+慢查询SQL+Redis+秒杀设计

头条Java一面 1.讲讲jvm运行时数据库区 2.讲讲你知道的垃圾回收算法 3.jvm内存模型jmm 4.内存泄漏与内存溢出的区别 5. select、epoll 的区别&#xff1f;底层的数据结构是什么&#xff1f; 6.mysql数据库默认存储引擎&#xff0c;有什么优点 7.优化数据库的方法&#xf…

CNN卷积神经网络(吴恩达《卷积神经网络》笔记一)

CNN 卷积网络说明卷积 Convolution填充 Padding步长 StrideRGB图像卷积池化 Pooling完整CNN为什么人们喜欢用卷积神经网络&#xff1f;实例分析说明 关于CNN的基础知识&#xff1a;卷积、填充、步长、池化、完整的深度CNN网络可以参考 链接: AI学习笔记——卷积神经网络&#…

字符串匹配算法(BM)

文章目录1. BM&#xff08;Boyer-Moore&#xff09;算法1.1 坏字符规则1.2 好后缀规则1.3 两种规则如何选择2. BM算法代码实现2.1 坏字符2.2 好后缀2.3 完整代码2.4 调试3. 总结1. BM&#xff08;Boyer-Moore&#xff09;算法 思想&#xff1a;有模式串中不存在的字符&#xf…

SQL 数据分析常用语句

1 基础查询 • 2 字符串数字日期时间 • 3 聚合数据查询 • 4 子查询 • 5 联接组合查询 • 6 高级查询 • 7 更新数据 阅读提醒&#xff1a;点击图片放大可看清晰的 1 基础查询 2 字符串数字日期时间 3 聚合数据查询 4 子查询 5 联接组合查询 6 高级查询 7 更新数据 参考资料 …

开源词法分析工具LAC重大升级!打造属于自己的个性化分词器!

星标/置顶小屋&#xff0c;带你解锁最萌最前沿的NLP、搜索与推荐技术文 | 匿名大佬编 | 北大小才女小轶本文将为大家介绍如何使用百度开源的词法分析工具LAC实现个性化分词&#xff08;附代码&#xff09;&#xff0c;并展示LAC在各数据集上惊艳的性能表现。背景介绍分词是中文…

老刘说NLP:这几年的NLP历程回顾,以及关于NLP(知识图谱等)落地的思考

得语言者&#xff0c;得天下。得语言资源者&#xff0c;分天下。得语言逻辑者&#xff0c;争天下。 前言 只有把自己所思考的&#xff0c;所认识的东西&#xff0c;以文字的方式记录下来&#xff0c;才是对自己成长最好的记录方式。 是的&#xff0c;距离上一次动手写博客或者…

Redis系列教程(一):Redis缓存的设计、性能、应用与数据集群同步

Redis 是完全开源免费的&#xff0c;遵守BSD协议&#xff0c;是一个高性能的key-value数据库。Redis本质上是一个Key-Value类型的内存数据库&#xff0c;很像memcached&#xff0c;整个数据库统统加载在内存当中进行操作&#xff0c;定期通过异步操作把数据库数据flush到硬盘上…

论文浅尝 | 提取计数量词丰富知识库

OpenKG 祝各位读者新年快乐&#xff01;论文标题&#xff1a;Enriching Knowledge Bases with Counting Quantifiers论文链接&#xff1a;https://link.springer.com/content/pdf/10.1007%2F978-3-030-00671-6_11.pdf发表会议&#xff1a;ISWC 2018论文源码&#xff1a;https:/…

RNN循环神经网络(吴恩达《序列模型》笔记一)

1、为什么选择序列模型 2、数学符号 用1来代表人名&#xff0c;0来代表非人名&#xff0c;句子x便可以用y[1 1 0 1 1 0 0 0 0]来表示 3、循环网络模型 值得一提的是&#xff0c;共享特征还有助于减少神经网络中的参数数量&#xff0c;一定程度上减小了模型的计算复杂度。 …

字符串匹配算法(KMP)

文章目录1. KMP由来2. KMP算法基本原理3. 代码4. Leetcode 28. 实现 strStr()1. KMP由来 上一节说的BM算法是最高效、最常用的字符串匹配算法。最知名的却是KMP&#xff0c;它3位作者&#xff08;D.E.Knuth&#xff0c;J.H.Morris&#xff0c;V.R.Pratt&#xff09;&#xff0…

常用的SQL语句

常用的SQL语句 一、基础 1、说明&#xff1a;创建数据库 CREATE DATABASE database-name 2、说明&#xff1a;删除数据库 drop database dbname 3、说明&#xff1a;备份sql server 1 --- 创建 备份数据的 device 2 3   USE master 4 5   EXEC sp_addumpdevice disk, te…

论文浅尝 | 用对抗学习做知识表示(NAACL2018)

论文链接&#xff1a;https://arxiv.org/pdf/1711.04071.pdf代码链接&#xff1a;https:// github.com/cai-lw/KBGAN 本文针对在生成负样本时有大部分负样本可以很好地和正样本区分开&#xff0c;对训练的影响不大&#xff0c;提出了使用生成对抗网络&#xff08;GANs&#xff…