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

news2024/11/25 18:42:15

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.coloradmin.cn/o/1451463.html

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

相关文章

OS文件管理

文件管理 文件的属性 文件所包含的属性&#xff1a; 文件名&#xff1a;由创建文件的用户决定文件名&#xff0c;主要为了方便用户找到文件&#xff0c;同一目录下不允许有重名文件。标识符&#xff1a;一个系统内的各文件标识符唯一&#xff0c;对用户来说毫无可读性&#…

2.12:C语言测试题

1.段错误&#xff1a;申请堆区内存未返回&#xff0c;str指向NULL 2.段错误&#xff1a;局部变量&#xff0c;本函数结束&#xff0c;p也释放 3.越界访问&#xff0c;可能正常输出hello&#xff0c;可能报错 4.可能段错误&#xff0c;释放后&#xff0c;str未指向NULL&#x…

CentOS7.9+Kubernetes1.29.2+Docker25.0.3高可用集群二进制部署

CentOS7.9Kubernetes1.29.2Docker25.0.3高可用集群二进制部署 Kubernetes高可用集群&#xff08;Kubernetes1.29.2Docker25.0.3&#xff09;二进制部署二进制软件部署flannel v0.22.3网络&#xff0c;使用的etcd是版本3&#xff0c;与之前使用版本2不同。查看官方文档进行了解…

The method toList() is undefined for the type Stream

The method toList() is undefined for the type Stream &#xff08;JDK16&#xff09; default List<T> toList() { return (List<T>) Collections.unmodifiableList(new ArrayList<>(Arrays.asList(this.toArray()))); }

C语言strstr函数

简介 strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是&#xff0c;则该函数返回 str1字符串从 str2第一次出现的位置开始到 str1结尾的字符串&#xff1b;否则&#xff0c;返回NULL。 实验 #include "stdio.h" #include "string.h"c…

2.14:二维数组、非函数实现strcat、strcmp、strcpy、strlen

1.编程实现二维数组的杨辉三角 程序代码&#xff1a; 1 #include<stdio.h>2 #include<string.h>3 #include<stdlib.h>4 int main(int argc, const char *argv[])5 {6 int n;7 printf("please enter n:");8 scanf("%d",&…

2024/02/13

21 、C 22 、D 23、B 如果5先出栈那么1&#xff0c;2&#xff0c;3&#xff0c;4就已经入栈了&#xff0c;5出后4出&#xff0c;1要出栈必须先让3&#xff0c;2出栈&#xff0c;所以 不可能输出B 24、10&#xff0c;12&#xff0c;120 25、2&#xff0c;5 26、段错…

2024.02.12作业

1. 段错误 2. 段错误 3. hello 4. world 5. int a; int* a; int **a; int a[10]; int* a[10]; int(* a)[10]; int* a(int); int (*a[10])(int); 6. 6&#xff1b; 2&#xff1b; 2 7. 2 8. 2 9. b 10. a 11. a 12. c 13. b 14. c 15. a 16. c 17. b 18. a 19…

消息中间件特点

1.  消息中间件概念 消息中间件是消息传递的过程中保存消息的容器。 主要目的&#xff1a;提供路由并保证消息的传递&#xff1b;如果发送消息时接受者不可用&#xff0c;消息队列会保留信息&#xff0c;直到可以成功传递为止。 消息中间件保存消息也是有期限的。 2.  消息…

JVM工作原理与实战(三十八):JIT即时编译器原理

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、JIT即时编译器 二、HotSpot中的JIT编译器 三、JIT优化技术 1.方法内联 2.逃逸分析 四、JIT优化建议 总结 前言 JVM作为Java程序的运行环境&#xff0c;其负责解释和执行字节…

[计算机网络]---序列化和反序列化

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、再谈协议…

《VulnHub》GoldenEye:1

title: 《VulnHub》GoldenEye&#xff1a;1 date: 2024-02-16 14:53:49 updated: 2024-02-16 15:08:49 categories: WriteUp&#xff1a;Cyber-Range excerpt: 主机发现、目标信息扫描、源码 js 文件泄露敏感信息、hydra 爆破邮件服务&#xff08;pop3&#xff09;、邮件泄露敏…

成考怎么搜题答案?9个受欢迎的搜题分享了 #微信#职场发展

大学生应该养成良好的时间管理习惯&#xff0c;合理分配学习、休息和娱乐的时间&#xff0c;避免压力过大或时间浪费。 1.Forest专注森林 Forest是一款专注与时间管理应用。当你需要专注于学习或工作时&#xff0c;你可以在Forest应用中种植一棵虚拟树&#xff0c;设定一段时…

幻兽帕鲁——游戏优化【腾讯云服务器联机版本】

幻兽帕鲁8人以内联机&#xff0c;闭眼参加【腾讯云幻兽帕鲁专属游戏活动】4核16G12兆 购买腾讯云服务器后&#xff0c;游戏一键部署&#xff0c;联机流程参照这个博文 【10秒开服】雾锁王国全自动部署教程-CSDN博客 幻兽帕鲁——游戏优化 1.设置虚拟内存 第一步&#xff1a…

selenium定位元素报错:‘WebDriver‘ object has no attribute ‘find_element_by_id‘

Selenium更新到 4.x版本后&#xff0c;以前的一些常用的代码的语法发生了改变 from selenium import webdriver browser webdriver.Chrome() browser.get(https://www.baidu.com) input browser.find_element_by_id(By.ID,kw) input.send_keys(Python)目标&#xff1a;希望通…

阿里云“BGP(多线)”和“BGP(多线)_精品”区别价格对比

阿里云香港等地域服务器的网络线路类型可以选择BGP&#xff08;多线&#xff09;和 BGP&#xff08;多线&#xff09;精品&#xff0c;普通的BGP多线和精品有什么区别&#xff1f;BGP&#xff08;多线&#xff09;适用于香港本地、香港和海外之间的互联网访问。使用BGP&#xf…

Linux:docker搭建redis集群(3主3从扩容缩容 哈希槽分配)

操作系统&#xff1a;centos7 docker-ce版本&#xff1a;24.0.7 1.准备redis镜像 我这里使用redis 6.0.8 镜像进行操作&#xff0c;如果你也需要镜像&#xff0c;在网络正常情况下直接使用 docker pull redis:6.0.8 即可进行下载&#xff0c;如果你没配置国内加速器&#x…

[java基础揉碎]数组 值拷贝和引用拷贝的赋值方式

目录 数组的介绍 为什么有数组 数组的三种使用方式 动态初始化: 静态初始化: 数组使用注意事项和细节 值拷贝和引用拷贝的赋值方式 数组反转: 数组拷贝: 数组的介绍 数组可以存放多个同一类型的数据。数组也是一种数据类型&#xff0c;是引用类型。 即&#xff1a;数组…

【蓝桥杯冲冲冲】[CEOI2015 Day2] 世界冰球锦标赛

蓝桥杯备赛 | 洛谷做题打卡day32 文章目录 蓝桥杯备赛 | 洛谷做题打卡day32题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示样例解释 题解代码我的一些话 [CEOI2015 Day2] 世界冰球锦标赛 题目描述 译自 CEOI2015 Day2 T1「Ice Hockey World Championship」 今年的…

[高并发] - 1.高并发综述

1. 必备条件 高并发&#xff0c;高性能分布式ID 高并发过滤组件 Bloom FIlter 2. 数据库 &#xff08;1&#xff09;不要让mysql干不擅长的工作&#xff0c;例如全文搜索&#xff0c;而是采用对应的nosql来处理&#xff1b;对于擅长的存取数据则能很好胜任&#xff1b; &am…