【洛谷题解/AcWing题解】USACO2.4 洛谷P1522 牛的旅行
本文很长但是讲的很通俗了。题目链接洛谷链接https://www.luogu.com.cn/problem/P1522AcWing链接https://www.acwing.com/problem/content/1127/涉及知识1.图论与建图2.多源汇最短路和Floyed算法思路分析注意本题洛谷翻译和AcWing翻译有所不同洛谷要求新牧场直径最小值AcWing要求所有牧场最大直径的最小值。本文先按洛谷的翻译写最后再讲求AcWing要求的结果该如何做。第一部分厘清概念首先本题给出了很多概念我们先来逐一解析牧区一个点牧场很多个牧区组成一个牧场也就是点的连通块距离两点间的最短距离本题的距离是欧几里得距离这就是为什么本题底层逻辑上还是需要用最短路算法的原因直径牧场中最远的两个牧区的距离第二部分建图与预处理在正式求解之前我们需要思考如何建图。本题我们可以根据给定的领接矩阵若领接矩阵中G [ i ] [ j ] G[i][j]G[i][j]的值为 1那么就根据给定坐标求点i ii到j jj的距离 如果值为 0 则按照 Floyed 算法的规则赋值为 0 或正无穷。由于本题其后都需要使用“距离”我们先跑一遍 Floyed 算法求出数组d i s [ i ] [ j ] dis[i][j]dis[i][j]记录任意两点间的最短路即本题的距离。然后我们进一步思考新牧场的直径可能是怎样构成的我们连接的两点i ii和j jj是未连通的两点也就是说在连接时i ii和j jj应当分属两个不同的连通块A AA和B BB那么新牧场直径就有可能有三种情况情况一连通块A AA的直径即经过A AA内某一点的最远距离可能不经过点i ii情况二连通块B BB的直径即经过B BB内某一点的最远距离可能不经过点j jj情况三经过点i ii的最远距离 经过点j jj的最远距离 点i ii和 点j jj之间的路径长度注意到这三种情况都与从某一点出发的最远距离息息相关所以我们在跑完 Floyed 后用一个数组m a x d maxdmaxd来记录每一点的最远路径。第三部分结果的求解对于洛谷的翻译如果是要求解新牧场的直径的最小值我们只需要保证连接两点i ii和j jj时m a x d [ i ] m a x d [ j ] maxd[i]maxd[j]maxd[i]maxd[j]i ii和j jj的距离之和最小即可因为原有牧场的直径已经是固定的这个跨牧场的直径即上文的情况三是要大于等于所有原牧场的直径的最大值的否则无法构成直径。这也是本题最绕的地方。举个例子比如情况一的直径是 33情况二的直径是 44情况三我们求出最小是 44.5那么情况一和二无法构成直径而情况三我们已经求的是最小值也就求出了直径的最小值。而如果情况一的直径是 33情况二的直径是 44情况三求出来是 40那情况三就不可能成为直径直径的最小值为44。如果我们故意“施魔法”让情况三的数超过 33 和 44则又不满足对最小值的要求了。开个玩笑但就是这么个道理综上我们可以发现我们只需要保证先求情况三的最小值就一定可以在三者中找到直径的最小值。因此最后我们只需要分别把三种情况的直径求出来再取最大值就一定是直径的最小值了。对于 AcWing 的翻译求的是所有牧场的直径的最小值唯一的区别在于处理洛谷的翻译的题目我们是分了两种情况再连通块A AA和B BB中求直径因为必须是新生成的牧场。没有这条限制后我们则不需要在代码中特判当前点是否属于两个连通块直接求所有点的最远距离m a x d [ i ] maxd[i]maxd[i]再与m a x d [ i ] m a x d [ j ] maxd[i]maxd[j]maxd[i]maxd[j]i ii和j jj的距离之和取最大值即可。与网上其他做法相比本做法最大的优点在于不需要使用并查集等数据结构思路更为精练代码更为简洁可迁移性也很强。笔者水平有限若有错误和不足敬请指出AC代码洛谷版#includeiostream#includecstdio#includecmathusingnamespacestd;constintN200;constdoubleINF1e20;typedefpairdouble,doublePII;intn;doubledis[N][N],maxd[N];charG[N][N];PII farm[N];doubleget_dist(PII x,PII y){doubledxx.first-y.first,dyx.second-y.second;returnsqrt(dx*dxdy*dy);}voidfloyed(){for(intk1;kn;k){for(inti1;in;i){for(intj1;jn;j){dis[i][j]min(dis[i][j],dis[i][k]dis[k][j]);}}}return;}intmain(){cinn;for(inti1;in;i)cinfarm[i].firstfarm[i].second;for(inti1;in;i){for(intj1;jn;j)cinG[i][j];}for(inti1;in;i){for(intj1;jn;j){if(G[i][j]1)dis[i][j]get_dist(farm[i],farm[j]);elsedis[i][j]ij?0:INF;}}floyed();for(inti1;in;i){for(intj1;jn;j){if(dis[i][j]INF)maxd[i]max(maxd[i],dis[i][j]);}}//两点连成的最大直径的最小值doubleres1INF;inta0,b0;for(inti1;in;i){for(intj1;jn;j){if(dis[i][j]INF){if(res1maxd[i]get_dist(farm[i],farm[j])maxd[j]){res1maxd[i]get_dist(farm[i],farm[j])maxd[j];ai,bj;}}}}//在连通块A中doubleres20.0;for(inti1;in;i){//判断点i和点a是否连通如果连通则说明在同一连通块中//但是这里取的是maxd[i]所以不一定会经过点aif(dis[i][a]INF)res2max(res2,maxd[i]);}//在连通块B中doubleres30.0;for(inti1;in;i){//同上if(dis[i][b]INF)res3max(res3,maxd[i]);}printf(%.6lf,max(res1,max(res2,res3)));// cout endl res1 res2 res3;return0;}AcWing版将情况一和二合并直接求出所有点的m a x d [ i ] maxd[i]maxd[i]的最大值#includeiostream#includecstdio#includecmathusingnamespacestd;constintN200;constdoubleINF1e20;typedefpairdouble,doublePII;intn;doubledis[N][N],maxd[N];charG[N][N];PII farm[N];doubleget_dist(PII x,PII y){doubledxx.first-y.first,dyx.second-y.second;returnsqrt(dx*dxdy*dy);}voidfloyed(){for(intk1;kn;k){for(inti1;in;i){for(intj1;jn;j){dis[i][j]min(dis[i][j],dis[i][k]dis[k][j]);}}}return;}intmain(){cinn;for(inti1;in;i)cinfarm[i].firstfarm[i].second;for(inti1;in;i){for(intj1;jn;j)cinG[i][j];}for(inti1;in;i){for(intj1;jn;j){if(G[i][j]1)dis[i][j]get_dist(farm[i],farm[j]);elsedis[i][j]ij?0:INF;}}floyed();for(inti1;in;i){for(intj1;jn;j){if(dis[i][j]INF)maxd[i]max(maxd[i],dis[i][j]);}}//两点连成的最大直径的最小值doubleres1INF;inta0,b0;for(inti1;in;i){for(intj1;jn;j){if(dis[i][j]INF){if(res1maxd[i]get_dist(farm[i],farm[j])maxd[j]){res1maxd[i]get_dist(farm[i],farm[j])maxd[j];ai,bj;}}}}doubleres20.0;for(inti1;in;i){res2max(res2,maxd[i]);}printf(%.6lf,max(res1,res2));// cout endl res1 res2 res3;return0;}

相关新闻

游戏开发中的缓动函数应用与LayaAir实践

游戏开发中的缓动函数应用与LayaAir实践

1. 缓动函数在游戏开发中的核心价值在游戏开发中,动画效果直接影响用户体验的品质感。想象一下,当角色从一个位置移动到另一个位置时,如果只是机械地直线匀速运动,会显得非常生硬不自然。而通过缓动函数,我们可以实现加…

2026/11/3 4:19:28 阅读更多 →
Unity游戏模组加载器MelonLoader从零到精通:安装、配置与排错全指南

Unity游戏模组加载器MelonLoader从零到精通:安装、配置与排错全指南

1. 项目概述:为什么你需要掌握MelonLoader? 如果你是一个Unity游戏的深度玩家,尤其是那些支持模组(Mod)的PC游戏,那么你一定对“模组加载器”这个词不陌生。它就像一把万能钥匙,打开了游戏官方内…

2026/11/2 12:22:39 阅读更多 →
利用AI助手高效规划Monorepo大型功能:从架构设计到代码生成

利用AI助手高效规划Monorepo大型功能:从架构设计到代码生成

如果你正在管理一个包含多个微服务、前端应用、共享库和工具脚本的复杂项目,那么最近一定被这些问题困扰过:为什么每次修改一个共享库,都要手动更新十几个依赖它的服务?为什么新同事要花一整天才能把整个开发环境跑起来&#xff1…

2026/10/29 17:20:11 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/3 1:09:25 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/2 10:46:11 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/2 10:47:40 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/3 2:27:21 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/2 10:46:31 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/2 10:46:26 阅读更多 →

日新闻

周新闻

月新闻