最小生成树(Kruskal算法及相关例题)

1.Kruskal算法概念以及基本思路

(1)概念:

克鲁斯卡尔算法是求连通网的最小生成树的另一种方法。它的时间复杂度为O(ElogE)(E是图G的边的总数),适合于求边稀疏的网的最小生成树 。

其基本思想是:假设连通网G,令最小生成树的初始状态为只有n个顶点且没有任何一条边的图T,概述图中每个顶点自成一个连通分量。在E中选择代价最小(即距离最短)的边,若该边依附的顶点分别在T中不同的连通分量上,则将此边加入到T中;否则,舍去此边而选择下一条代价最小的边。换而言之就是在整个图找最短的边,从短到长一次寻找,若没有连通,则进行连通,若已经连通,则放弃这个边,去寻找下一个,知道变成连通图

(2)基本思路:

从它的基本思想我们可以得出做题时的基本思路:

1.首先创建一个一维数组,用于判断这个点是否连通,每个数组的初始值都对应自己的下标

2.创建一个结构体,存储位置信息,以及之间的长度

3.通过快排进行排序,将路径最短的排在前面

4.根据题解去寻找最小生成树

2.相关例题

第一题:最小生成树

 

题解:这题就是最基本的最小生成树问题,没有什么难度

#include<bits/stdc++.h>
using namespace std;int n,m;//n个结点和m条边
struct lu//代表路径的结构体
{int start;//起始节点int end1;//终止结点int l;//路径长度
}q[200005];
int f[50005];//用于判断是否连通的数组
int count1;//统计已经连通几条边
long long sum;//总长度int cha(int x)//查,判断是否属于同一个根节点
{if(f[x]==x)return x;return cha(f[x]);
}void bing(int root1,int root2)//并,将根节点并在一起
{if(root1==root2)return;f[root2]=root1;
}bool cmp(lu a,lu b)//路径要根据路径长度进行比较
{return a.l<b.l;//快排顺序,从小到大排列路径长度
}int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){f[i]=i;//将根节点设置为自己}for(int i=0;i<m;i++){scanf("%d%d%d",&q[i].start,&q[i].end1,&q[i].l);}sort(q+1,q+m+1,cmp);//快排for(int i=0;i<m;i++){if(cha(q[i].start)==cha(q[i].end1))//如果已经并在一起就直接跳过continue;bing(cha(q[i].start),cha(q[i].end1));sum+=q[i].l;count1++;if(count1==n-1)//当满足了连通图,这个是连通图的性质,边数=顶点数-1break;}if(count1<n-1)//如果是非连通图{printf("orz");return 0;}printf("%d",sum);return 0;
}

第二题:拆地毯

题解:这题其实就是最小生成树的地方略变一点儿,求的是最大生成树,我们要找的是最长的长度,那么我们只需要改变一下快排的方式即可

AC代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,k;
struct lu
{int start;int end1;int l;
}q[100005];
int f[100005];
int count1;
int sum;
int cha(int x)
{if(f[x]==x)return x;return cha(f[x]);
}
void bing(int root1,int root2)
{if(root1==root2)return ;f[root2]=root1;
}
bool cmp(lu a,lu b)
{return a.l>b.l;//改变一下快排的方式
}
int main()
{scanf("%d%d%d",&n,&m,&k);for(int i=1;i<=n;i++)f[i]=i;for(int i=0;i<m;i++){scanf("%d%d%d",&q[i].start,&q[i].end1,&q[i].l);}sort(q,q+m,cmp);for(int i=0;i<m;i++){if(cha(q[i].start)==cha(q[i].end1))continue;bing(cha(q[i].start),cha(q[i].end1));count1++;sum+=q[i].l;if(count1==k)//当保留的地毯满足保留的个数结束就可以break;}printf("%d",sum);return 0;
}

第三题:无线通讯网

题解:也是最小生成树类的题目,但是没什么的,唯一改变的地方就是因为这个地方不是求路径和,而是卡的最小的无线电所需要的距离,也就是卡的极限最小值

#include<bits/stdc++.h>
using namespace std;
int s,p;
int x[505],y[505];
int f[1000005];
struct lu
{int start;int end1;double l;
}q[2000005];
int count1;
double sum;
int cha(int x)
{if(f[x]==x)return x;return cha(f[x]);
}
void bing(int root1,int root2)
{if(root1==root2)return ;f[root2]=root1;	
}
bool cmp(lu a,lu b)
{return a.l<b.l;
}
int main()
{int flag=0;scanf("%d%d",&s,&p);for(int i=1;i<=p;i++)f[i]=i;for(int i=1;i<=p;i++){scanf("%d%d",&x[i],&y[i]);for(int j=1;j<i;j++){flag++;q[flag].start=i;q[flag].end1=j;q[flag].l=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));}}sort(q+1,q+1+flag,cmp);for(int i=1;i<=flag;i++){if(cha(q[i].start)==cha(q[i].end1))continue;sum=q[i].l;//长度就是那个极限的值bing(cha(q[i].start),cha(q[i].end1));count1++;if(count1==p-s)//当满足了结束条件break;}printf("%.2lf",sum);return 0;
}

第四题:营救

题解:也是最小生成树的题目和第三题其实一样,只不过排的是拥挤度

AC代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,s,t;
struct lu
{int start;int end1;int l;
}q[20005];
int f[10005];
int count1;
int sum;
int cha(int x)
{if(f[x]==x)return x;return cha(f[x]);
}
void bing(int root1,int root2)
{if(root1==root2)return ;f[root2]=root1;
}
bool cmp(lu a,lu b)
{return a.l<b.l;
}
int main()
{scanf("%d%d%d%d",&n,&m,&s,&t);for(int i=1;i<=n;i++)f[i]=i;for(int i=0;i<m;i++){scanf("%d%d%d",&q[i].start,&q[i].end1,&q[i].l);}sort(q,q+m,cmp);for(int i=0;i<m;i++){bing(cha(q[i].start),cha(q[i].end1));sum=q[i].l;if(cha(s)==cha(t)){break;}}printf("%d",sum);return 0;
}

第五题:买礼物

题解:这题有一个坑,就是有可能绑定在一起买比单个买还要贵,因此我们在进行价值的计算时需要有一个判断

#include<bits/stdc++.h>
using namespace std;
int a,b;
struct wu
{int x,y;int w;
}q[250005];
int f[505];
int sum;
int count1;
int cha(int x)
{if(f[x]==x)return x;return cha(f[x]);
}
void bing(int root1,int root2)
{if(root1==root2){return ;}f[root2]=root1;
}
bool cmp(wu a,wu b)
{return a.w<b.w;
}
int main()
{scanf("%d%d",&a,&b);sum=a;for(int i=1;i<=b;i++)f[i]=i;for(int i=1;i<=b;i++){for(int j=1;j<=b;j++){count1++;scanf("%d",&q[count1].w);q[count1].x=i;q[count1].y=j;if(q[count1].w==0)q[count1].w=a;}}sort(q+1,q+1+count1,cmp);for(int i=1;i<=count1;i++){if(cha(q[i].x)==cha(q[i].y))continue;bing(cha(q[i].x),cha(q[i].y));sum+=min(q[i].w,a);//去优惠价格和原价格的小值}printf("%d",sum);return 0;
}

 第六题:Building Roads S

 题解:这题也是很简单的和无线电那个在处理坐标的方式差不多,但是恶心的地方在于精度的把控,需要在原本的精度上更加细致不然还是会WA,血的教训,也是一开始就中计了啊,大意了,没有闪

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

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

相关文章

黄金交易策略(Nerve Nnife.mql4):做单手数设计

完整EA&#xff1a;Nerve Knife.ex4黄金交易策略_黄金趋势ea-CSDN博客 NK的做单量是由参数设定的&#xff0c;以下分别是参数项&#xff1a; 考虑到复利的情况&#xff0c;若10000本金&#xff0c;在以上三个参数的设计下&#xff0c;第1单的购买量是0.01*10,第2单是0.01*10*2…

Java迭代器详解,看这一篇就够了

文章目录 &#x1f6a9;Java 迭代器详解 &#x1f4da;迭代器的定义 &#x1f4d2;认识Iterator ✏️类结构图 ✒️Iterable接口 &#x1f58d;️Iterator接口 &#x1f4c3;Iterator接口的方法 &#x1f4d9;迭代器的使用 &#x1f3f7;️使用迭代器遍历集合 &#x1f516;Ite…

ES实战--集群扩展

查看ES集群状态: GET /_cluster/health?prettytrue当一个节点加入集群的时候,ES会自动地尝试将分片在所有节点上进行均匀分配. 如果更多的节点加入集群,ES将试图在所有节点上均匀分配分片数量.这样每一个新加入的节点都能通过部分数据来分担负载 第二个节点发现第一个节点,并…

[BIZ] - 1.金融交易系统特点

1. 典型数据汇总 数据 说明 新增数据量(条/天) Qps(条/s) 消息大小(Byte) 实时性 可丢失性 可恢复性 实时行情 1.使用场景&#xff1a;交易&#xff0c;报价&#xff0c;策略验证&#xff1b; 2.冷热分离&#xff1a;彭博行情/其他行情&#xff1b;黄金&期货行情/…

数组操作C

数组操作 Description 给你一个长度为 n 的数组&#xff0c;并给出如下几种操作&#xff1a; 在下标为 a 的位置插入一个整数 b&#xff0c;如果其后有元素&#xff0c;则全部后移。例如&#xff0c;数组为 1, 2, 3&#xff0c;在下标为 1 的位置插入 4&#xff0c;则数组变为…

acwing周赛115第二题-奶牛照相

5132. 奶牛照相 - AcWing题库 约翰的农场有 n 头奶牛&#xff0c;编号 1∼n。 其中&#xff0c;第 i 头奶牛的宽度为 wi&#xff0c;高度为 hi&#xff0c; 有一天&#xff0c;它们聚餐后决定拍照留念。 关于拍照的描述如下&#xff1a; 它们一共拍了 n 张照片&#xff0c;其中…

PyQt5中exec()与exec_()的区别

在PyQt5中&#xff0c;exec()和exec_()是两个不同的方法&#xff0c;用于执行动态创建的Python代码。它们的主要区别在于exec()是Python的关键字&#xff0c;但不能直接用作方法名&#xff0c;因此在PyQt5中&#xff0c;使用exec_()作为替代。 exec_()方法接受一个字符串作为参…

debian11 安装 k8s,containerd ,阿里云镜像(已成功)

1. 环境准备 系统要求&#xff1a;至少 2GB RAM&#xff08;建议 4GB 或更多&#xff09;&#xff0c;网络连接。 节点准备&#xff1a;至少 3 台机器&#xff0c;1 台作为 Master 节点&#xff0c;2 台作为 Worker 节点。 安装sudo apt update apt install sudo设置主机名&a…

Java图形化界面编程——AWT概论 笔记

2.3 Container容器 2.3.1 Container继承体系 Winow是可以独立存在的顶级窗口,默认使用BorderLayout管理其内部组件布局;Panel可以容纳其他组件&#xff0c;但不能独立存在&#xff0c;它必须内嵌其他容器中使用&#xff0c;默认使用FlowLayout管理其内部组件布局&#xff1b;S…

Spring Cloud Feign:声明式服务调用

1. 介绍 Spring Cloud Feign 1.1 什么是 Spring Cloud Feign Spring Cloud Feign 是一个基于 Netflix Feign 的声明式服务调用客户端&#xff0c;它简化了基于 REST 的服务调用&#xff0c;使得服务之间的通信变得更加轻松和直观。通过 Feign&#xff0c;开发人员可以像调用本…

交通管理|交通管理在线服务系统|基于Springboot的交通管理系统设计与实现(源码+数据库+文档)

交通管理在线服务系统目录 目录 基于Springboot的交通管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户信息管理 2、驾驶证业务管理 3、机动车业务管理 4、机动车业务类型管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计…

MySQL学习Day15——MySQL安装与使用

一、Linux下的MySQL的安装与使用: 卸载MySQL: 1.关闭当前MySQL服务:systemctl stop mysql.service 2.查看当前mysql安装状况:rpm -qa | grep -i mysql 3.卸载上述命令查询出的已安装的程序:yum remove mysql-xxx mysql-xxx mysql-xxxx 4.删除mysql相关文件: (1)查找相关文…

Python五级考试笔记

Python五级考试笔记【源源老师】 五级标准 一、 掌握字符串的转义符、format()格式化方法。 二、 掌握列表、元组、字符串、range类型的用法及常用操作。 三、 理解字典类型的概念&#xff0c;掌握它的基础用法及操作。 四、 理解集合类型的概念&#xff0c;掌握它的基础用法及…

解决vscode报错,在赋值前使用了变量“XXX“

问题&#xff1a;如图所示 解决方法&#xff1a; 法一&#xff1a; 补全函数使其完整 法二&#xff1a; 使用断言

c++Qt网络操作

1、基础概念 1.1 TCP/UDP TCP 是一种面向连接的传输层协议&#xff0c;它能提供高可靠性通信(即数据无误、数据无丢失、 数据无失序、数据无重复到达的通信) 适用情况&#xff1a; 1.SN/QQ等即时通讯软件的用户登录账户管理相关的功能通常采用TCP协议 2、适合于对传输质量要求较…

【STM32 CubeMX】串口编程DMA

文章目录 前言一、DMA方式1.1 DMA是什么1.2 CubeMX配置DMA1.3 DMA方式函数使用DMA的发送接收函数 总结 前言 在嵌入式系统中&#xff0c;串口通信是一项至关重要的功能&#xff0c;它允许单片机与外部设备进行数据交换&#xff0c;如传感器、显示器或其他设备。然而&#xff0…

Linux笔记之xhost +和docker的关系以及GDK_SCALE和GDK_DPI_SCALE详解

Linux笔记之xhost 和docker的关系以及GDK_SCALE和GDK_DPI_SCALE详解 ——2024-02-11 code review! 文章目录 Linux笔记之xhost 和docker的关系以及GDK_SCALE和GDK_DPI_SCALE详解xhost 的作用xhost 与 Docker 的关系 -e GDK_SCALE 和 -e GDK_DPI_SCALE详解GDK_SCALEGDK_DPI_SC…

【使用IntelliJ IDEA 配置Maven入门——详细讲解】

使用IntelliJ IDEA 配置Maven 1. 介绍2. 安装 Maven&#xff08;如果你的系统尚未安装&#xff09;3. 在 IntelliJ IDEA 中配置 Maven4. 创建/导入 Maven 项目5. 编译和运行 Maven 项目6. 提示 1. 介绍 IntelliJ IDEA 是一个广受欢迎的Java集成开发环境&#xff08;IDE&#x…

【Linux】进程的初步认识

进程的初步认识 基本概念描述进程task_struct-PCB的一种task_stuct内容分类 查看进程通过系统调用获取进程标识符 基本概念 要了解进程&#xff0c;首先我们要知道两点 我们可以同时启动多个程序&#xff0c;也就意味着我们可以将多个.exe文件加载到内存操作系统如何去管理这些…

Resolving Low-Level Graphics Issues

Resolving Low-Level Graphics Issues 在远程操作其他工作站上的matlab的时候&#xff0c;无法显示仿真结果&#xff0c;但是在真实的工作站上操作的话又可以看到simulation的结果&#xff0c;并且远程的时候进行仿真&#xff0c;就会显示以下的错误提示&#xff1a; >>…