最小生成树(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)//当满足了连通图,这个是连通图的性质,边数=顶点数-1
		break;
	}
	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.mfbz.cn/a/390483.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JDBC访问数据库

目录 加载Driver驱动配置驱动地址 获取数据库连接创建会话-SQL命令发送器通过Statement发送SQL命令并得到结果处理结果关闭数据库资源测试 加载Driver驱动 1.在模块JDBC中新建一个lib目录文件 2. 将mysql-connector-j-8.2.0包粘贴至lib目录中。 配置驱动地址 // 加载…

Nvidia 携手 RTX 推出的本地运行 AI 聊天机器人

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

人工智能学习与实训笔记(三):神经网络之目标检测问题

目录 五、目标检测问题 5.1 目标检测基础概念 5.1.1 边界框&#xff08;bounding box&#xff09; 5.1.2 锚框&#xff08;Anchor box&#xff09; 5.1.3 交并比 5.2 单阶段目标检测模型YOLOv3 5.2.1 YOLOv3模型设计思想 5.2.2 YOLOv3模型训练过程 5.2.3 如何建立输出…

uni-app 经验分享,从入门到离职(二)—— tabBar 底部导航栏实战基础篇

文章目录 &#x1f4cb;前言⏬关于专栏 &#x1f3af;关于小程序 tabbar 的一些知识&#x1f3af;创建一个基本的 tabBar&#x1f4dd;最后 &#x1f4cb;前言 这篇文章的内容主题是关于小程序的 tabBar 底部导航栏的入门使用和实战技巧。通过上一篇文章的基础&#xff0c;我们…

【sgCreateTableColumn】自定义小工具:敏捷开发→自动化生成表格列html代码(表格列生成工具)[基于el-table-column]

源码 <template><!-- 前往https://blog.csdn.net/qq_37860634/article/details/136126479 查看使用说明 --><div :class"$options.name"><div class"sg-head">表格列生成工具</div><div class"sg-container"…

C++,stl,常用排序算法,常用拷贝和替换算法

目录 1.常用排序算法 sort random_shuffle merge reverse 2.常用拷贝和替换算法 copy replace replace_if swap 1.常用排序算法 sort 默认从小到大排序 #include<bits/stdc.h> using namespace std;int main() {vector<int> v;v.push_back(1);v.push_ba…

RabbitMQ如何保证可靠

0. RabbitMQ不可靠原因 消息从生产者到消费者的每一步都可能导致消息丢失&#xff1a; 发送消息时丢失&#xff1a; 生产者发送消息时连接MQ失败生产者发送消息到达MQ后未找到Exchange生产者发送消息到达MQ的Exchange后&#xff0c;未找到合适的Queue消息到达MQ后&#xff0c;…

idea里微服务依赖在maven能install但不能启动

场景&#xff1a;多个微服务相互依赖&#xff0c;install都没问题&#xff0c;jar包都是正常的&#xff0c;就连jar都能启动&#xff0c;为什么在idea里面项目就是不能启动呢&#xff0c;我是懵逼的 所以解决办法就是&#xff1a; 在设置的编译器里面虚拟机选项添加 -Djps.tr…

第五节 zookeeper集群与分布式锁_2

1.分布式锁概述 1.1 什么是分布式锁 1&#xff09;要介绍分布式锁&#xff0c;首先要提到与分布式锁相对应的是线程锁。 线程锁&#xff1a;主要用来给方法、代码块加锁。当某个方法或代码使用锁&#xff0c;在同一时刻仅有一个线程执行该方法或该代码段。 线程锁只在同一J…

LEETCODE 164. 破解闯关密码

class Solution { public:string crackPassword(vector<int>& password) {vector<string> password_str;for(int i0;i<password.size();i){password_str.push_back(to_string(password[i]));}//希尔排序int gappassword.size()/2;while(gap>0){for(int i…

命令执行讲解和函数

命令执行漏洞简介 命令执行漏洞产生原因 应用未对用户输入做严格得检查过滤&#xff0c;导致用户输入得参数被当成命令来执行 命令执行漏洞的危害 1.继承Web服务程序的权限去执行系统命会或读写文件 2.反弹shell&#xff0c;获得目标服务器的权限 3.进一步内网渗透 远程代…

python----输入输出算数运算

1.格式化输出 如果我们直接打印输出&#xff0c;就是输出变量的值&#xff0c;例如&#xff1a; 如果我们想打印a10就需要格式化字符串&#xff0c;就是使用f进行格式化&#xff0c;如图所示&#xff1b; 2.控制台输入 input执行的时候&#xff0c;就会等待用户进行输入&…

Qlik Sense : 条形图

条形图 “条形图适合比较多个值。维度轴显示所比较的类别条目&#xff0c;度量轴显示每个类别条目的值。” Qlik Sense中的条形图是一种数据可视化工具&#xff0c;用于展示不同类别或维度之间的比较。它通过水平或垂直的条形表示数据&#xff0c;并根据数值的大小进行排序。…

RK3568平台开发系列讲解(存储篇)文件描述符相关系统调用实现

🚀返回专栏总目录 文章目录 一、open 系统调用二、close 系统调用沉淀、分享、成长,让自己和他人都能有所收获!😄 一、open 系统调用 open()系统调用会分配新的文件句柄(file description),用来维护与打开文件相关的元信息(如偏移量、路径、操作方法等),并会给进程…

微信小程序框架阐述

目录 一、框架 响应的数据绑定 页面管理 基础组件 丰富的 API 二、逻辑层 App Service 小程序的生命周期 注册页面 使用 Page 构造器注册页面 在页面中使用 behaviors 使用 Component 构造器构造页面 页面的生命周期 页面路由 页面栈 路由方式 注意事项 模块化…

Git 初学

目录 一、需求的产生 二、版本控制系统理解 1. 认识版本控制系统 2. 版本控制系统分类 &#xff08;1&#xff09;集中式版本控制系统 缺点&#xff1a; &#xff08;2&#xff09;分布式版本控制系统 三、初识 git 四、git 的使用 例&#xff1a;将 “ OLED文件夹 ”…

单部10层电梯控制系列之UDT数据类型的建立(SCL代码)

这篇博客开始介绍单部10层电梯的完整控制程序编写过程&#xff0c;编程语言&#xff1a;SCL&#xff0c;控制器型号&#xff1a;S7-1200PLC。开篇博客我们介绍电梯控制用到的所有UDT数据类型。在学习本篇博客之前大家可以参考下面文章&#xff0c;了解博途PLC里的UDT数据类型是…

紫微斗数双星组合:天机太阴在寅申

文章目录 前言内容总结 前言 紫微斗数双星组合&#xff1a;天机太阴在寅申 内容 紫微斗数双星组合&#xff1a;天机太阴在寅申 性格分析 天机星与太阴星同坐寅申二宫守命的男性&#xff0c;多浪漫&#xff0c;易与女性接近&#xff0c;温柔体贴&#xff0c;懂得女人的心理。…

.NET Core WebAPI中使用Log4net记录日志

一、安装NuGet包 二、添加配置 // log4net日志builder.Logging.AddLog4Net("CfgFile/log4net.config");三、配置log4net.config文件 <?xml version"1.0" encoding"utf-8"?> <log4net><!-- Define some output appenders -->…

上位机图像处理和嵌入式模块部署(图像项目处理过程)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 对于一般的图像项目来说&#xff0c;图像处理只是工作当中的一部分。在整个项目处理的过程中有很多的内容需要处理&#xff0c;比如说了解需求、评…