洛谷P5021 [NOIP 2018 提高组] 赛道修建【题解】【二分答案+树上贪心】

P5021 [NOIP 2018 提高组] 赛道修建

题意简述

给定一棵含 n n n 个点的无向带权树,求将其分裂为 m m m 条链后,最短的一条链的最大长度是多少?

点可以重复使用,边不可以重复使用。

思路

二分答案贪心判定貌似可以?

看一下数据规模。

a i = 1 a_i = 1 ai=1 ,菊花图。链最多含两条边。

b i = a i + 1 b_i = a_i + 1 bi=ai+1 ,整棵树是一条链。

分支不超过 3 3 3 ?感觉在有意引导。是二叉树。

菊花图是最有用的,考虑菊花图时如何求解。设当前二分出的赛道长度为 m i d mid mid

显然此时一条链最多含两条边,考虑按边权排序:

1**.已经大于 m i d mid mid 的边**不必再拼接其他边,因为它已经能产生贡献了,再与其他边拼接,自身贡献不变的同时,阻止了其他边产生贡献的可能,必然不优。

2.剩下的边里,从小到大,对于每个边 x x x二分(减小查询复杂度)查询出与它拼接能产生长度大于 m i d mid mid最短的一条边,即找到最小的 y y y ,满足 x + y ≥ m i d x + y \ge mid x+ymid

为什么?如果用更长的边( > y > y >y ),那么可能会使得原本可以产生贡献的 y y y 被抛弃,又因为自身不够长而无法再次与别的边产生贡献,相反,被使用的更长边显然更有可能与别的边拼接产生贡献,因此选择最小的 y y y 即可。

菊花图的情况已经可以求解。不妨把每一个子树视作上述菊花图的情况,现在子树内已经得到最优解,如何向父节点扩展?

由于每个结点到父节点的边是唯一的,那么只能选择一条边传递给父节点,供后续产生贡献,那么,不难想到传递 剩余未匹配边最长的一条。因为最长,后续产生贡献的概率越大,缓解了父节点的匹配压力,保证了全局最优解。可以用 d p [ u ] dp[u] dp[u] 表示当前结点最长未匹配边,到父节点出只需将父节点的边权加上 d p [ u ] dp[u] dp[u] 即可。

当子树求解完成时,与子节点相连的边指向哪里已经不再重要,只需记录并排序边权即可,用 m u l t i s e t multiset multiset

代码实现

其实细节很多:

1.C++11 及以上erase 返回删除指定元素后下一个有效迭代器。

2.在 m u l t i s e t multiset multiset 中查找到第一个大于等于 y y y 的元素时一定要判断,有可能就是自己,如果未判断就删除会引起各种奇怪错误。

  1. 我因为 r e s = m res = m res=m 放在 d f s dfs dfs 后,调了半天全输出 0 0 0
#include <bits/stdc++.h>using namespace std;const int N = 5e4 + 100;
int n,m,L = INT_MAX,R,res,ans; 
bool vis[N];
struct Edges{int v,w;
};
vector <Edges> gra[N];void read(int &res){int x = 0,w = 1;char ch = 0;while(ch < '0' || ch > '9'){if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){x = (x << 3) + (x << 1) + (ch - '0');ch = getchar();}res = x * w;
}bool cmp(Edges a,Edges b){return a.w < b.w;
}int dfs(int u,int limit){vis[u] = true;//记录与子树相连的边 int cnt = 0;multiset <int> match;//优先在子树内求解for(auto edge : gra[u]){int v = edge.v;//连接父亲的边跳过 if(vis[v]) continue;match.insert(edge.w + dfs(v,limit));} //在当前子树匹配//长度已经满足的 for(auto it = match.begin();it != match.end();)if(*it >= limit){it = match.erase(it);res--;  }else{it++;}
//	需要两两匹配的for(auto it = match.begin();it != match.end();){int y = limit - (*it);auto _it = match.lower_bound(y);if(_it == match.end() || _it == it){it++;continue; } res--;match.erase(_it);it = match.erase(it);} if(match.empty()) return 0;return *match.rbegin();
}void solve(){int l = L,r = R,mid;while(l <= r){mid = l + r >> 1;memset(vis,false,sizeof(vis));res = m;dfs(1,mid);if(res <= 0){l = mid + 1;ans = mid;}else r = mid - 1;	}printf("%d\n",ans);
} int main(){read(n);read(m);int u,v,w;for(int i = 1;i < n;i++){read(u);read(v);read(w);gra[u].push_back({v,w});gra[v].push_back({u,w});L = min(L,w);R += w;}//二分答案solve(); return 0;
}

挺好的一道树上二分+贪心。

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

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

相关文章

Portal认证过程杂谈

Portal认证模型简介 Portal认证模型通常由这四个设备组成 认证服务器即3A服务器&#xff0c;通常用radius服务器 接入设备通常就是NAC设备&#xff08;网络接入控制&#xff09; Portal服务器就是Portal认证的认证网站&#xff08;通常叫门户网站&#xff09; 认证过程简述…

ZSGuardian ---AI赋能,新一代研发管理守护平台 -即将上线

一场研发管理的革命 在数字化浪潮奔涌向前的今天&#xff0c;软件开发与产品研发的节奏不断加快&#xff0c;市场需求瞬息万变&#xff0c;技术迭代日新月异。对于研发团队而言&#xff0c;如何在复杂多变的环境中&#xff0c;高效地管理项目、保障产品质量、确保按时上线&…

小菜狗的云计算之旅,学习了解rsync+sersync实现数据实时同步(详细操作步骤)

Rsyncsersync实现数据实时同步 目录 Rsyncsersync实现数据实时同步 一、rsync概述 二、rsync运行原理 三、rsync部署 四、备份测试 五、使用非系统用户备份数据 5.1 rsync的配置文件介绍 5.2 配置备份目录 5.3 使用rsync用户备份测试 5.4 pull拉取数据 六、rsyncse…

牛客周赛Round 99(Go语言)

A题 (A.go) 思路总结: 这道题要求判断一个整数中是否包含连续的两个9。 核心思路是将输入的整数转换为字符串&#xff0c;然后遍历这个字符串&#xff0c;检查是否存在相邻的两个字符都是9。如果找到了&#xff0c;就立即停止遍历并输出"YES"&#xff1b;如果遍历完…

红外图像小目标检测热力图可视化系统

原创代码&#xff0c;可以工程修改含界面。

供应链管理:指标评估方式分类与详解

一、指标评估方式分类与详解 评估维度评估方式核心方法适用场景示例数据来源内部数据评估从企业ERP、MES、CRM等系统提取生产、财务、客户等数据。成本、效率、质量等内部管理指标评估。生产成本数据&#xff08;MES系统&#xff09;、客户满意度&#xff08;CRM系统&#xff…

基于 Rust 的前端工具基本实现

1. Rust 环境安装 1.1. 安装 Rust Rust 提供了一个非常方便的安装工具 rustup,可以通过以下命令安装 Rust: curl --proto =https --tlsv1.2 -sSf https://sh.rustup.rs | sh 这个命令会安装 Rust 编译器 rustc、包管理工具 cargo 以及其他相关工具。 1.2. 配置环境变量 …

大模型关键字解释

&#x1f4a1; 一、模型结构关键词 1. Transformer Transformer 是一种专门用来“理解文字”的神经网络结构。就像一个聪明的秘书&#xff0c;能同时看懂整段话的所有词之间的关系&#xff0c;而不是像老式模型那样一句一句读。 &#x1f449; 举例&#xff1a;以前的模型像…

空调和烘干机的使用

开关 制冷 选择上下扫风 那个就下来了 烘干机 电源键 长按3s以上直到菜单显示 选择小件 不要快烘 至少1个半小时 才可以烘干

极简的神经网络反向传播例子

我之前一直没搞清楚&#xff0c;神经网络为什么要求导&#xff1f;反向传播又是什么&#xff1f;于是到现在深究回来…… 本质就是拟合一个未知函数。 高中的数理统计就学过最小二乘法这种回归方法&#xff08;ŷ 代表自己的预测y&#xff0c;这个表达要记住&#xff09;&…

01-什么是强化学习

什么是强化学习 1. 定义 强化学习&#xff08;Reinforcement Learning, RL&#xff09;是一种使智能体&#xff08;Agent&#xff09;通过与环境&#xff08;Environment&#xff09;不断交互&#xff0c;学习如何在不同情境下采取行动以获得最大化累积奖励的机器学习方法。 强…

淘宝直播数字人:音视频算法工程技术

本专题是我们打造智能数字人的部分实践总结。我们将探讨六大核心环节&#xff1a;LLM文案生产赋予数字人思考和内容生成能力&#xff0c;如同其“大脑”&#xff1b;LLM互动能力则聚焦对话逻辑与拟人化交流&#xff0c;是实现自然交互的关键&#xff1b;TTS&#xff08;语音合成…

MySQL回表查询深度解析:原理、影响与优化实战

引言 作为后端开发或DBA&#xff0c;你是否遇到过这样的场景&#xff1a; 明明给字段加了索引&#xff0c;查询还是慢&#xff1f;EXPLAIN一看&#xff0c;执行计划里type是ref&#xff0c;但数据量不大却耗时很久&#xff1f; 这时候&#xff0c;你很可能遇到了MySQL中常见的…

任务管理器看不到的内存占用:RAMMap 深度分析指南

前言&#xff1a;任务管理器看不到的内存真相 在日常使用 Windows 系统时&#xff0c;我们有时会遇到一种令人费解的情况&#xff1a; 刚刚开机&#xff0c;什么软件都没运行&#xff0c;系统内存却已经占用了 7&#xff5e;8 GB。 打开任务管理器一看&#xff0c;前几个进程加…

从传统仓库到智能物流枢纽:艾立泰的自动化蜕变之旅

在物流行业智能化浪潮中&#xff0c;艾立泰从依赖人工的传统仓库转型为智能物流枢纽&#xff0c;其自动化升级路径为行业提供了典型范本。​曾几何时&#xff0c;艾立泰仓库内人工搬运、纸质单据流转、手工盘点是常态&#xff0c;效率低下、差错率高、人力成本攀升等问题制约发…

408第三季part2 - 计算机网络 - 滑动窗口

理解 帧本质就是一堆二进制&#xff0c;后面会将帧的格式 流量控制就是 B&#xff1a;急急急急急急 A&#xff1a;别急 A控制B&#xff0c;B控制C&#xff0c;C控制D&#xff0c;但D无法控制A&#xff0c;这就是相邻节点 abc在发送的过程中发送完了 怎么才能继续发送呢 没…

RedHat高可用集群深度解析与优化

一、RHCS核心组件深度解析1. Corosync&#xff08;消息层&#xff09;通信机制改进说明&#xff1a; Totem协议采用环形令牌传递机制&#xff0c;在10节点以下集群中使用UDP/IP组播&#xff08;224.0.0.12&#xff09;&#xff0c;超过10节点建议改用UDP/UDP单播。典型配置示例…

为什么使用 XML Schema?

为什么使用 XML Schema? XML(可扩展标记语言)是一种广泛使用的标记语言,它被设计用来存储和传输数据。XML Schema 是一种用于定义 XML 文档结构的语言,它为 XML 文档提供了严格的验证机制。以下是使用 XML Schema 的几个主要原因: 1. 结构化数据定义 XML Schema 允许开…

ESP32蓝牙学习笔记

蓝牙 官网&#xff1a;https://www.bluetooth.com/zh-cn/learn-about-bluetooth/tech-overview/ 概述 分类&#xff1a;Bluetooth经典、Bluetooth低能耗(LE) GAP 通用访问配置文件(Generic Access Profile, GAP)简称GAP&#xff0c;该Profile保证不同的Bluetooth产品可以互…

C#扩展方法全解析:给现有类型插上翅膀的魔法

C#扩展方法全解析&#xff1a;给现有类型插上翅膀的魔法 在 C# 的类型系统中&#xff0c;当我们需要为现有类型添加新功能时&#xff0c;传统方式往往意味着继承、重写或修改源代码 —— 但如果是string、int这样的系统类型&#xff0c;或是第三方库中的密封类&#xff0c;这些…