【算法每日一练]-图论(保姆级教程篇9 最小生成树 ,并查集篇)#道路修建 #兽径管理

本文主要是介绍【算法每日一练]-图论(保姆级教程篇9 最小生成树 ,并查集篇)#道路修建 #兽径管理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

题目:道路修建

思路: 

题目:兽径管理

思路:


        

        

题目:道路修建

                

思路: 

“让这些点全部连在一起的最小代价”很明显是最小生成树。绝对不能kruskal,存边一定会超内存。所以只能prim。

但是这些点之间的边我们还是不能存,最好的方式就是一边建树一边计算距离

因为我们每次都要取距离集合最小的点,那么我们就要维护一个dis数组

                

思路是这样的:

集合中的点到集合距离一定是0,

集合外的点到集合的距离一定需要与集合中的每个点的距离进行比较取最小值。

但是如果说集合每变动一次,集合外的点就把集合中的点全部遍历一遍非常没必要。

因为之前已经比较过的点根本就不用再比较,基于这个思想。
我们完全可以在集合中每个元素进入集合的时候进行比较就行,

这样相当于是把新进入集合的元素要和集合外的所有元素进行距离更新即可
计算方式为:dis[j]=min(dis[j],cur到j的距离)
        

#include <bits/stdc++.h>
using namespace std;
int n,cnt;
double sum;
int vis[5005];
double dis[5005],x[5005],y[5005];//dis是每个点到集合的最小距离double cal(double x1,double y1,double x2,double y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); 
}
void prim()
{dis[1]=0;vis[1]=1;for(int i=1;i<=n;i++){//一共要n个点全部进入集合int cur=1;double minn=1e9*1.0;for(int j=1;j<=n;j++)if(!vis[j]&&dis[j]<minn){//获取最近点minn=dis[j];cur=j;}vis[cur]=1;sum+=dis[cur];for(int j=1;j<=n;j++){if(!vis[j])dis[j]=min(dis[j],cal(x[cur],y[cur],x[j],y[j]));}}printf("%.2lf",sum);
}int main()
{cin>>n;for(int i=1;i<=n;i++){scanf("%lf%lf",&x[i],&y[i]);;//输入每个点的坐标dis[i]=1e12*1.0;}prim();
}

        

        

        

题目:兽径管理

        

思路:

这么长的题你应该也不会读,我捋一下:

牛群希望能够在任意两块草地间移动,草地编号1~n,共w周牛群每周发现一个新路,输出每周任意两块草地路径总和,如果不能到达就输出-1。

                

这道题本来不难的,我花了一下午找bug,结果发现又tm在排序上犯老毛病了!(原数组是有序的)别学我啊

        
原来的边是按照时间顺序的,现在一排序就不知道原来的出现时间了,那么就需要增加一个id记录出现时间,也是边原来的标号。

        
第一种解法是每周跑一次,kruskal时间晚于本周的边不统计
第二种解法是倒着进行kruskal。在最后一周跑的kruskal上统计用到的边,每往前一周删一条边,如果这条边没有被用到,那么使用上个结果,否则重跑。
        

         

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=205,M=6005;
int f;
struct Edge{ int u,v,w,id; }e[M];
int fa[N],n,m;
int use[M],vis[M];//vis表示被删掉的边,use表示在上次结果中被用到的边
ll ans[M];bool cmp(Edge a,Edge b){ return a.w<b.w;}void init(){for(int i=1;i<=n;i++) fa[i]=i;//初始化并查集节点memset(use,0,sizeof(use));
}
int find(int x)
{if(x!=fa[x]) fa[x]=find(fa[x]);return fa[x];//返回祖先 
}ll kruskal()
{init();ll tmp=0;int cnt=0;for(int i=1;i<=m;i++){if(vis[e[i].id])continue;//此边要判断边的id是否已经被删掉了int fu=find(e[i].u), fv=find(e[i].v);if(fu==fv) continue;  //若出现两个点已经联通了,则说明这一条边不需要了tmp+=e[i].w; //将此边权计入答案use[e[i].id]=1;//对id标记fa[fv]=fu; //合并操作if(++cnt==n-1)break;}return cnt==n-1?tmp:-1;
}int main()
{cin>>n>>m;for(int i=1;i<=m;i++){scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w);e[i].id=i;//记录边的id号}sort(e+1,e+1+m,cmp);//将边的权值排序ans[m]=kruskal();for(int i=m-1;i>0;i--){//从id开始删边,倒着删边嘛vis[i+1]=1;//对id号删除if(use[i+1]) ans[i]=kruskal();//id被用过else ans[i]=ans[i+1];if(ans[i]==-1){for(int j=1;j<i;j++) ans[j]=-1;break;}}for(int i=1;i<=m;i++)cout<<ans[i]<<'\n';return 0;
}

这篇关于【算法每日一练]-图论(保姆级教程篇9 最小生成树 ,并查集篇)#道路修建 #兽径管理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/438217

相关文章

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

基于C#实现PDF转图片的详细教程

《基于C#实现PDF转图片的详细教程》在数字化办公场景中,PDF文件的可视化处理需求日益增长,本文将围绕Spire.PDFfor.NET这一工具,详解如何通过C#将PDF转换为JPG、PNG等主流图片... 目录引言一、组件部署二、快速入门:PDF 转图片的核心 C# 代码三、分辨率设置 - 清晰度的决定因

SpringBoot集成XXL-JOB实现任务管理全流程

《SpringBoot集成XXL-JOB实现任务管理全流程》XXL-JOB是一款轻量级分布式任务调度平台,功能丰富、界面简洁、易于扩展,本文介绍如何通过SpringBoot项目,使用RestTempl... 目录一、前言二、项目结构简述三、Maven 依赖四、Controller 代码详解五、Service

Python从Word文档中提取图片并生成PPT的操作代码

《Python从Word文档中提取图片并生成PPT的操作代码》在日常办公场景中,我们经常需要从Word文档中提取图片,并将这些图片整理到PowerPoint幻灯片中,手动完成这一任务既耗时又容易出错,... 目录引言背景与需求解决方案概述代码解析代码核心逻辑说明总结引言在日常办公场景中,我们经常需要从 W

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

Java Scanner类解析与实战教程

《JavaScanner类解析与实战教程》JavaScanner类(java.util包)是文本输入解析工具,支持基本类型和字符串读取,基于Readable接口与正则分隔符实现,适用于控制台、文件输... 目录一、核心设计与工作原理1.底层依赖2.解析机制A.核心逻辑基于分隔符(delimiter)和模式匹

Linux系统管理与进程任务管理方式

《Linux系统管理与进程任务管理方式》本文系统讲解Linux管理核心技能,涵盖引导流程、服务控制(Systemd与GRUB2)、进程管理(前台/后台运行、工具使用)、计划任务(at/cron)及常用... 目录引言一、linux系统引导过程与服务控制1.1 系统引导的五个关键阶段1.2 GRUB2的进化优

spring AMQP代码生成rabbitmq的exchange and queue教程

《springAMQP代码生成rabbitmq的exchangeandqueue教程》使用SpringAMQP代码直接创建RabbitMQexchange和queue,并确保绑定关系自动成立,简... 目录spring AMQP代码生成rabbitmq的exchange and 编程queue执行结果总结s