【题解】NOIP2018 赛道修建
\(\text{Solution:}\)
根据题目信息简化题意,是让你在树上找出\(m\)条路径使得路径长度最小值最大。
看到题第一感先二分一个答案,问题转化为如何选择一些路径使得它们最小值都大于当前二分的答案。
观察一个节点的子树,必然会带着若干链。它们有些合法,有些需要拼凑成一条合法路径。
于是,我们令\(val[x]\)表示这条路径以\(x\)结尾的长度。将\(x\)所连接的所有路径提取出来。
贪心地,我们显然要使得\(x\)所连的这一条路径最大。所以在给其他路径拼凑的时候要用尽量小的链来凑出合法路径。
于是,我们对所有提取出的路径排序并二分,找到和它可以匹配的最优路径,并标记。
对于二分到的点,我们可以向后枚举直到一个未被标记的点。
最后复杂度是\(O(n\log^2 n).\)注意\(vis\)数组用当前点做编号可以免去清空。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
const int inf=(1<<30);
int n,m,tot=1,head[MAXN],rt,Siz[50001],mson[50001],M;
int val[50001],up,vis[100010],q[100010];
struct E{int nxt,to,dis;}e[MAXN];
inline void add(int x,int y,int w){
e[++tot].to=y;e[tot].nxt=head[x];
e[tot].dis=w;head[x]=tot;
}
int Gr(int x,int fa){
int sum1=0,sum2=0;
Siz[x]=1;mson[x]=0;
for(int i=head[x];i;i=e[i].nxt){
int j=e[i].to;
if(j==fa)continue;
sum2=max(sum2,Gr(j,x)+e[i].dis);Siz[x]+=Siz[j];
if(Siz[j]>mson[x])mson[x]=Siz[j];
if(sum1<sum2)swap(sum1,sum2);
}
if(n-Siz[x]>mson[x])mson[x]=n-Siz[x];
if(M>mson[x])M=mson[x],rt=x;
up=max(up,sum1+sum2);
return sum1;
}
inline bool checkedge(int v1,int v2,int ck){return (v1+v2)>=ck;}
int dfs(int x,int fa,int v){
int cnt=0,ans=0;
if(ans>=m)return ans;
for(int i=head[x];i;i=e[i].nxt){
int j=e[i].to;
if(j==fa)continue;
ans+=dfs(j,x,v);
}
for(int i=head[x];i;i=e[i].nxt){
int j=e[i].to;
if(j==fa)continue;
if(val[j]+e[i].dis>=v){
ans++;
continue;
}
q[++cnt]=e[i].dis+val[j];
}
sort(q+1,q+cnt+1);
for(int i=1;i<=cnt;++i){
if(vis[i]==x)continue;
int L=i+1,R=cnt,AA=0;
while(L<=R){
int mid=L+R>>1;
if(checkedge(q[i],q[mid],v))AA=mid,R=mid-1;
else L=mid+1;
}
while(vis[AA]==x&&AA<=cnt)AA++;
if(AA>cnt)continue;
if(vis[AA]==x)continue;
if(AA&&checkedge(q[i],q[AA],v)){
vis[AA]=x;vis[i]=x;
ans++;continue;
}
}
for(int i=cnt;i>=1;--i){
if(vis[i]==x)continue;
val[x]=q[i];break;
}
return ans;
}
bool check(int x){
for(int i=1;i<=n;++i)val[i]=0,vis[i]=vis[i+n]=-1;
int A=dfs(rt,0,x);
return A>=m;
}
int main(){
scanf("%d%d",&n,&m);
int l=1,r;
for(int i=1;i<n;++i){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);add(y,x,z);
}
M=inf;Gr(1,0);r=up;
int ans=0;
while(l<=r){
int mid=l+r>>1;
if(check(mid))l=mid+1,ans=mid;
else r=mid-1;
}
printf("%d\n",ans);
return 0;
}
【题解】NOIP2018 赛道修建的更多相关文章
- 竞赛题解 - NOIP2018 赛道修建
\(\mathcal {NOIP2018}\) 赛道修建 - 竞赛题解 额--考试的时候大概猜到正解,但是时间不够了,不敢写,就写了骗分QwQ 现在把坑填好了~ 题目 (Copy from 洛谷) 题 ...
- 【LG5021】[NOIP2018]赛道修建
[LG5021][NOIP2018]赛道修建 题面 洛谷 题解 NOIP之前做过增强版还没做出来\(QAQ\) 一看到题目中的最大值最小,就很容易想到二分答案 重点是考虑如何\(check\) 设\( ...
- Luogu5021 [NOIP2018]赛道修建
Luogu5021 [NOIP2018]赛道修建 一棵大小为 \(n\) 的树,边带权.选 \(m\) 条链使得长度和最小的链最大. \(m<n\leq5\times10^4\) 贪心,二分答案 ...
- [NOIP2018]赛道修建(二分+multiset)
考场上打了一个 \(vector\) 解法,因为我当时不会 \(multiset\) 好吧,我来讲一讲今年的 \(tgD1T3\) 首先,这题 \(55\) 分是不难想的 1. \(b_i=a_i+1 ...
- 【比赛】NOIP2018 赛道修建
最小值最大,二分长度 然后判断赛道大于等于这个长度最多可以有多少条 可以贪心,对于一个点和它的一些儿子,儿子与儿子之间尽量多配(排序后一大一小),剩下的选个最长的留给自己的父亲就好了 具体实现可以用一 ...
- [NOIP2018]赛道修建
嘟嘟嘟 因为一些知道的人所知道的,不知道的人所不知道的原因,我来改写今年的NOIP了. 现在看这题,心中满是疑问:我当时是多么的zz,这种水题为啥没做出来-- 不管了,说正事. 先考虑部分分. 1.\ ...
- luogu5021 [NOIp2018]赛道修建 (二分答案+dp(贪心?))
首先二分一下答案,就变成了找长度>=m的 不相交的路径的个数 考虑到在一个子树中,只有一个点能出这个子树去和别的点搞 所以我这个子树里尽量自我满足是不会有坏处的 而且要在自我满足数最大的条件下, ...
- 题解 NOIP2018【赛道修建】—— 洛谷
这道题有一点点树上dp的意思(大佬轻喷 我刚拿到这道题的时候毫无头绪,只知道这道题要二分答案 为什么是二分答案??? 题目: 目前赛道修建的方案尚未确定.你的任务是设计一 种赛道修建的方案,使得修建的 ...
- [NOIp2018提高组]赛道修建
[NOIp2018提高组]赛道修建 题目大意: 给你一棵\(n(n\le5\times10^4)\)个结点的树,从中找出\(m\)个没有公共边的路径,使得第\(m\)长的路径最长.问第\(m\)长的路 ...
随机推荐
- SQL Server解惑——标识列的限制和跳号现象
1:每个表只能创建一个标识列. 如下测试所示,如果表中有一个标识列,新增一个标识列就会遇到错误"Multiple identity columns specified for table ...
- 目标识别AI资料
朋友推荐的, 还有自己搜的. 入门可以看看. 网上资料应该不少, 一搜一大把, 简单记下地址. Review of Deep Learning Algorithms for Object Detect ...
- 阿里云体验实验室 体验教程《Linux指令入门-系统管理》
体验平台简介 阿里云开发者实验室提供免费云资源和丰富的场景化实践,旨在帮助开发者在学习应用技术,了解阿里云产品的特性. 阿里云体验实验室地址:https://developer.aliyun.com/ ...
- 【小白学PyTorch】8 实战之MNIST小试牛刀
文章来自微信公众号[机器学习炼丹术].有什么问题都可以咨询作者WX:cyx645016617.想交个朋友占一个好友位也是可以的~好友位快满了不过. 参考目录: 目录 1 探索性数据分析 1.1 数据集 ...
- 【Go语言入门系列】(九)写这些就是为了搞懂怎么用接口
[Go语言入门系列]前面的文章: [Go语言入门系列](六)再探函数 [Go语言入门系列](七)如何使用Go的方法? [Go语言入门系列](八)Go语言是不是面向对象语言? 1. 引入例子 如果你使用 ...
- 关于Vue-CLI的那些事儿
Vue CLI是基于Vue.js进行快速发展的完整系统,提供了: 交互式的项目脚手架 实现零配件的原型开发 图形化的创建和管理项目的界面 基本框架的构建: . ├── build/ # webpack ...
- whlie do-whlie
switch语句 用于根据多个不同条件执行不同动作. while 循环 while循环基本语法: 条件初始化; while(条件表达式){ //条件表达式就是判 ...
- 一个SQL查询连续三天的流量100以上的数据值【SQql Server】
题目 有一个商场,每日人流量信息被记录在这三列信息中:序号 (id).日期 (date). 人流量 (people).请编写一个查询语句,找出高峰期时段,要求连续三天及以上,并且每天人流量均不少于10 ...
- 微信小程序 部署(后台是springboot项目 前后台分流)
微信小程序的部署需要https 和证书: https 需要反向代理: 这里用 nginx,无论linux,windows 系统都可以安装: 1.安装nginx ,这步自己去做: linux 安装ngi ...
- 【吴恩达课程使用】anaconda (python 3.7) win10安装 tensorflow 1.8 cpu版
[吴恩达课程使用]anaconda (python 3.7) win10安装 tensorflow 1.8 目前tensorflow是只支持到python3.6的,anaconda最新版本已经到pyt ...