【算法每日一练]-图论(保姆级教程篇7 最小生成树 ,并查集模板篇)#村村通 #最小生成树

目录

题目:村村通

并查集 

题目:最小生成树

kruskal算法

prim算法


        

先引入问题:

要在n个城市之间铺设光缆,主要目标是要使这 n 个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同,因此另一个目标是要使铺设光缆的总费用最低。这就需要找到带权的最小生成树

说白了就是将此图连通起来的最小代价。

        

对于一个有N个点的图,边一定是大于等于N-1条的。图的最小生成树,就是在这些边中选择N-1条出来,连接所有的N个点。这N-1条边的边权之和是所有方案中最小的

有两种算法:prim和kruskal

前者适合稠密图,后者适合稀疏图(不然炸你内存)

        

        

要先说并查集才行

题目:村村通

        

并查集 

【并查集思想】:是集合。一个是并操作(建树),一个是查操作(查树)。并操作是将一个集合的树变成另一个集合树的子树。

        
我们只需要建和原图等价的并查树即可,根本不用建原图
查操作是从该元素开始查找父节点直到找到根节点看看是否相同

        
1,初始化每个点的父亲为自身
2,并操作:(建边)合并两个集合的树根(祖宗)(查的过程中并路径压缩)
3,查操作:最后查找有几个祖宗即可

#include <bits/stdc++.h>              
using namespace std;
int fa[1000001], n, m, x, y;
int find(int x)
//找到祖先后并修改中间点的fa(路径压缩使更快的查到祖宗,
//其实就是对树进行优化,减少了树的深度,效果是将多代变成一代) 
{if(x!=fa[x]) fa[x]=find(fa[x]);
//自己不是祖宗,直接更新成亲爹的祖宗号
//但是如果是dp,那就要先保存原亲爹号,不然你就找不到爹了(路径压缩的代价)return fa[x];//返回祖先 
}
void unity(int x, int y)
{int f1=find(x);//如果x和y本来就在同一个集合完全 不影响int f2=find(y);fa[f1]=f2;//合并树根 
}
int main()
{while(true){int ans=0;cin>>n>>m;if(n==0) return 0;for(int i=1; i<=n; i++){fa[i]=i;//先初始化成节点}for(int i=1; i<=m; i++){scanf("%d %d", &x, &y);//合并<x,y>能到的地方unity(x,y);//建边,建树}for(int i=1; i<=n; i++){//一共有几个祖宗if(find(i)==i) ans++;}printf("%d\n", ans-1);//共需修ans-1条路即可}return 0;
}

         

         

题目:最小生成树

         

kruskal算法

【kruskal】:贪心的每次取最小权值的边进行合并(只要不构成环),当恰好合并了n-1条边时候就是最小生成树。只要小于就不是,此图也不连通
可以使用并查集来实现合并和不构成环

                
kruskal甚至不需要建图,但是如果是完全图的话,存边容易MLE,这时候就要prim

#include<bits/stdc++.h>
using namespace std;
int f;
struct Edge{ int u,v,w; }e[200005];
int fa[5005],n,m,ans,cnt;bool cmp(Edge a,Edge b){ return a.w<b.w;}int find(int x)
{if(x!=fa[x]) fa[x]=find(fa[x]);return fa[x];//返回祖先 
}void kruskal()
{sort(e+1,e+1+m,cmp);//将边的权值排序for(int i=1;i<=m;i++){int fu=find(e[i].u), fv=find(e[i].v);if(fu==fv) continue;  //若出现两个点已经联通了,则说明这一条边不需要了ans+=e[i].w; //将此边权计入答案fa[fv]=fu; //合并操作if(++cnt==n-1)//如果边数恰好为n-1,则说明最小生成树已经建成{f=1;break;}}
}int main()
{cin>>n>>m;for(int i=1;i<=n;i++) fa[i]=i;//初始化并查集节点for(int i=1;i<=m;i++){scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w);}kruskal();if(f==1)printf("%d",ans);else cout<<"orz";//不连通return 0;
}

         

prim算法

【prim算法】:prim算法基于贪心,我们每次总是选出一个离生成树距离最小的点去加入生成树,最后实现最小生成树(不做证明,理解思想即可)

每次都最小生成数和dijkstra思想很像,都是从小图开始,每次都从周围合并一个最小的点然后不断扩大,所以长得也很像,感觉完全一样啊

#include <bits/stdc++.h>
using namespace std;
int k,n,m,cnt,sum;
int head[5005],dis[5005],vis[5005];
typedef pair <int,int> pii;
struct Edge{ int v,w,next;}e[400005];void add(int u,int v,int w){e[++k]=(Edge){v,w,head[u]};head[u]=k;}void prim()
{priority_queue <pii,vector<pii>,greater<pii> > q;memset(dis,0x3f,sizeof(dis));dis[1]=0;//dis是周围点到集合的最小距离q.push(make_pair(0,1));while(!q.empty()&&cnt<n)//cnt是已经加入的点数{int d=q.top().first,u=q.top().second;//取出周围最小dis的点q.pop();if(vis[u]) continue;cnt++;sum+=d;vis[u]=1;//标记此点已经加入for(i=head[u];i;i=e[i].next){int ve=e[i].v,vw=e[i].w;//到集合最小距离就是权值if(vw<dis[ve])//如果变小就更新入队,以便获取最小的点dis[ve]=vw,q.push(make_pair(dis[ve],ve));}}
}int main()
{int u,v,w;scanf("%d%d",&n,&m);for(i=1;i<=m;i++){scanf("%d%d%d",&u,&v,&w);add(u,v,w);add(v,u,w);}prim();if (cnt==n)printf("%d",sum);else printf("orz");//如果小于n说明不连通
}

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

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

相关文章

线程池在Java中的应用实践

摘要&#xff1a;在实际业务场景中&#xff0c;线程池发挥着重要作用。本文将详细解答在高并发、任务执行时间短、并发不高、任务执行时间长以及并发高、业务执行时间长的业务场景下&#xff0c;如何使用线程池进行优化。 一、高并发、任务执行时间短的业务场景 在高并发、任务…

多平台小程序编译适配,是否会让更多App互联互通?

随着科技的飞速发展&#xff0c;我们正迅速进入一个以数字化为主导的时代。 在这个时代中&#xff0c;通信、小程序、快应用、云服务器等平台连接类软件如火如荼的发展&#xff0c;手机、手表、AR/VR眼镜等智能移动穿戴设备迅速的升级迭代&#xff0c;5G、芯片、算力等基础设施…

[Linux] Linux入门必备的基本指令(不全你打我)

一:ls指令 语法 &#xff1a; ls [选项] [目录或文件] 功能 &#xff1a;对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。对于文件&#xff0c;将列出文件名以及其他信息。 ls不带选项就是显示当前目录下存在的子目录和文件 常用选项: (1). ls -l 功能: 列出…

工业产品3d交互展示数字云展厅更绿色环保

随着数字技术的飞速发展&#xff0c;3D全景汽车云展厅平台应运而生&#xff0c;为现代展览带来了前所未有的创新与变革。该平台以其独特的优点&#xff0c;为观众、艺术家和展商带来了全新的展览体验&#xff0c;开启了未来展览的新篇章。 首先&#xff0c;3D全景汽车云展厅平台…

JDBC参数之allowMultiQueries

其实allowMultiQueries参数是一个比较基础的参数&#xff0c;见名知意 支持多SQL执行的参数。 适用场景 其实这个参数是ORM框架中使用的&#xff0c;可能很多人误以为是MySQL的参数&#xff0c;其实并不是。 例如下面这个mybatis sql脚本&#xff0c;最终生成的SQL应该是多个…

有n件物品(n<=13),每件物品的的花费为c[i],每个背包的容量为w,求最少要几个背包才能装下所有物品

题目 #include<bits/stdc.h> using namespace std; const int maxn 15; int cnt[maxn]; bool ok[1 << maxn];//ok[i]表示以状态i装物品&#xff0c;一个背包能不能装下 int f[1 << maxn];//f[i]表示以状态i&#xff08;二进制数&#xff0c;0表示不装&…

【数据结构复习之路】树和二叉树(严蔚敏版)万字详解主打基础

专栏&#xff1a;数据结构复习之路 复习完上面四章【线性表】【栈和队列】【串】【数组和广义表】&#xff0c;我们接着复习 树和二叉树&#xff0c;这篇文章我写的非常详细且通俗易懂&#xff0c;看完保证会带给你不一样的收获。如果对你有帮助&#xff0c;看在我这么辛苦整理…

数据结构与算法python版本一

没有学习过数据结构算法之类专业毕业的&#xff0c;因为特地学习了下&#xff0c;收货挺多&#xff0c;记录下~ 我们编写计算机程序的目的是解决我们实际的应用问题 首先 计算机科学研究的是什么 计算机科学不仅仅是对计算机的研究 计算机科学主要研究的是问题、问题解决过程以…

Linux虚拟化的模式

三种虚拟化方式&#xff1a;完全虚拟化&#xff08;Full virtualization&#xff09;、硬件辅助虚拟化&#xff08;Hardware-Assisted Virtualization&#xff09;、半虚拟化&#xff08;Paravirtualization&#xff09;。 服务器上的虚拟化软件&#xff0c;多使用 qemu&#…

蚁剑低版本反制

蚁剑低版本反制 漏洞概述 中国蚁剑是一款开源的跨平台网站管理工具&#xff0c;它主要面向于合法授权的渗透测试安全人员以及进行常规操作的网站管理员。影响范围 AntSword <2.0.7 蚁剑实验版本&#xff1a;2.0.7 环境搭建&#xff1a; 172.16.1.233&#xff08;蓝队服…

idea打开.class文件没有反编译

1 问题描述 新安装的idea开发工具&#xff0c;打开.class文件查看内容时发现没有将文件进行反编译&#xff0c;所以具体的代码实现看不到。如图所示&#xff1a; 尝试了各种办法解决&#xff0c;最终都没有解决我的问题&#xff0c;其他同事的idea开发工具都可以打开.class文件…

js闭包的必要条件及创建和消失(生命周期)

>创建闭包的必要条件&#xff1a; 1.函数嵌套 2.内部函数引用外部函数的变量 3.将内部函数作为返回值返回 >闭包是什么&#xff1f; 就是可以访问外部函数&#xff08;作用域&#xff09;中变量的内部函数 > 闭包是什么时候产生的&#xff1f; - 当调用外部函数…

HIT_OS_LAB4 系统调用

实验内容 编写iam.c和whoami.c iam.c #define __LIBRARY__ #include <unistd.h>// 定义系统调用 iam&#xff0c;参数为字符串 name _syscall1(int, iam, const char*, name);int main(int argc, char **argv) {int wlen 0;// 检查命令行参数数量if (argc < 2) {pri…

ELK+Filebeat

Filebeat概述 1.Filebeat简介 Filebeat是一款轻量级的日志收集工具&#xff0c;可以在非JAVA环境下运行。 因此&#xff0c;Filebeat常被用在非JAVAf的服务器上用于替代Logstash&#xff0c;收集日志信息。实际上&#xff0c;Filebeat几乎可以起到与Logstash相同的作用&…

VMware 系列:您当前正在评估模式下使用ESXi。此许可证将在60 天后过期

您当前正在评估模式下使用ESXi。此许可证将在60 天后过期 本人的ESXI版本为6.7。点击下方的分配许可证:一些序列号仅供参考:6.7VMware vSphere ESXi 7.0 Enterprise PlusVMware vSphere 7 Enterprise Plus with Add-on for KubernetesVMware vCenter 7.0 StandardVMware vSph…

使用C++编写代码实现字符串的拼接操作

C中有多种方法实现字符串拼接&#xff0c;以下是两种常见的方法&#xff1a; 方法一&#xff1a;使用加号“” #include <iostream> #include <string>using namespace std;int main() {string str1 "Hello";string str2 "World";string s…

Android11编译第八弹:root用户密码设置

问题&#xff1a;user版本增加su 指令以后&#xff0c;允许切换root用户&#xff0c;但是&#xff0c;root用户默认没有设置密码&#xff0c;这样访问不安全。 需要增加root用户密码。 一、Linux账户管理 1.1 文件和权限 Linux一切皆文件。文件和目录都有相应的权限&#x…

【Python】(自定义函数)模块的相对路径导入

是我以前写的老文章的升级版&#xff0c;本质上使用exec和sys.path实现相对路径导入。 RelativeImport&#xff1a; __version__1.1.0 __author__Ls_Janimport os import sys import inspectdef RelativeImport(module,*args):#模块导入module为模块所在路径(模块名不需要.py后…

函数式编程:简洁与效率的完美结合

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…