传送门

考场上把暴力都打满了,结果文件输入输出写错了....

当时时间很充裕,如果认真想想正解是可以想出来的..

问你 长度最小的赛道长度的最大值

显然二分答案

考虑如何判断是否可行

显然对于一个节点,它最多只能向父亲传一条路径长度

那么其它路径的合并只能在子树间进行

贪心一波,如果一段路径在子树就可以合并出合法长度

那么直接合并一定是不会比传给父亲再考虑合并更劣的

子树都合并完后,剩下的肯定传最长的长度给父亲

考虑在子树内如何贪心地进行最优合并

显然最小的边去找最小的能使它合法的边合并

(注意不是最大的边去找最小的能使它合法的边合并)

那么用一个multiset存一下当前节点的各个边长

然后就按前面的方法一个个合并就好了

注意和并时的一些细节和二分的上界,(因为multiset常数大,所以要把上界设为总长除赛道数)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
const int N=1e5+,INF=2e9+;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
int fir[N],from[N<<],to[N<<],val[N<<],cntt;
inline void add(int &a,int &b,int &c)
{
from[++cntt]=fir[a];
fir[a]=cntt; to[cntt]=b; val[cntt]=c;
}
int n,m,mid,cnt;
int f[N];
multiset <int> S;
multiset <int>::iterator it,itt,pit;
void dfs(int x,int fa)
{
for(int i=fir[x];i;i=from[i])
{
int &v=to[i]; if(fa==v) continue;
dfs(v,x);//先把每个节点遍历一波再从后往前更新会比较方便(不然要开一堆set)
}
S.clear();//记得清空
for(int i=fir[x];i;i=from[i])
{
int &v=to[i]; if(fa==v) continue;
if(f[v]+val[i]>=mid) cnt++;//只考虑小于mid的长度的合并(大于的不用合并都有贡献)
else S.insert(f[v]+val[i]);//注意把儿子传的边长加上父子间的边长
}
it=S.begin();
while(it!=S.end())
{
itt=S.lower_bound(mid-(*it));
if(itt==it) itt++;//注意细节
if(itt!=S.end()) cnt++,S.erase(itt),pit=it,it++,S.erase(pit);
else it++;
}
f[x]=;/*记得先清空f*/ it=S.begin(); if(S.end()!=it) it=S.end(),it--,f[x]=*it;//注意必须有边传才更新f
} inline int judge()
{
cnt=; dfs(,);
return cnt>=m;
} int main()
{
int a,b,c,s=;
n=read(); m=read();
for(int i=;i<n;i++)
{
a=read(); b=read(); c=read();
add(a,b,c); add(b,a,c); s+=c;
}
int L=,R=s/m;
while(R-L>)
{
mid=L+R>>;
if(judge()) L=mid; else R=mid;
}
mid=R;
printf("%d",judge() ? R : L);
return ;
}

P5021 赛道修建 (NOIP2018)的更多相关文章

  1. 洛谷P5021 赛道修建 NOIp2018 贪心+二分答案

    正解:贪心+LCA+二分答案 解题报告: 想先港下部分分qwq因为我部分分只拿到了10ptsQAQ(时间不够不是理由,其实还是太弱,所以要想很久,所以才时间不够QAQ m=1 找直径长度,完 一条链 ...

  2. 【题解】 P5021赛道修建

    [题解]P5021 赛道修建 二分加贪心,轻松拿省一(我没有QAQ) 题干有提示: 输出格式: 输出共一行,包含一个整数,表示长度最小的赛道长度的最大值. 注意到没,最小的最大值,还要多明显? 那么我 ...

  3. 二分答案 + multiset || NOIP 2018 D1 T3 || Luogu P5021 赛道修建

    题面:P5021 赛道修建 题解:二分答案,用Dfs进行判断,multiset维护. Dfs(x,fa,Lim)用来计算以x为根的子树中有多少符合条件的路径,并返回剩余未使用的最长路径长. 贪心思想很 ...

  4. P5021 赛道修建[贪心+二分]

    题目描述 C 城将要举办一系列的赛车比赛.在比赛前,需要在城内修建 mm 条赛道. C 城一共有 nn 个路口,这些路口编号为 1,2,-,n1,2,-,n,有 n-1n−1 条适合于修建赛道的双向通 ...

  5. [NOIp2018] luogu P5021 赛道修建

    我同学的歌 题目描述 你有一棵树,每条边都有权值 did_idi​.现在要修建 mmm 条赛道,一条赛道是一条连贯的链,且一条边至多出现在一条赛道里.一条赛道的长被定义为,组成这条赛道的边的权值之和. ...

  6. 洛谷P5021 赛道修建

    题目 首先考虑二分,然后发现最小长度越大的话,赛道就越少.所以可以用最终的赛道个数来判断长度是否合理.问题转化为给定一个长度,问最多有多少条互不重叠路径比这个给定长度大. 考虑贪心,毕竟贪心也是二分c ...

  7. P5021 赛道修建 题解

    原题链接 简要题意: 在一棵树上求 \(m\) 条不相交的路径的最小值的最大值. 本题部分分很多,而且本人也交了 \(27\) 次,所以一定要仔细讲部分分! 算法一 对于 \(b_i = a_i + ...

  8. Luogu5021 [NOIP2018]赛道修建

    Luogu5021 [NOIP2018]赛道修建 一棵大小为 \(n\) 的树,边带权.选 \(m\) 条链使得长度和最小的链最大. \(m<n\leq5\times10^4\) 贪心,二分答案 ...

  9. [NOIp2018提高组]赛道修建

    [NOIp2018提高组]赛道修建 题目大意: 给你一棵\(n(n\le5\times10^4)\)个结点的树,从中找出\(m\)个没有公共边的路径,使得第\(m\)长的路径最长.问第\(m\)长的路 ...

随机推荐

  1. spring bean属性及子元素使用总结

    spring bean属性及子元素使用总结 2016-08-03 00:00 97人阅读 评论(0) 收藏 举报  分类: Spring&SpringMVC(17)  版权声明:本文为博主原创 ...

  2. matlab学习笔记(3)

    数据分析: 多项式: 多项式表示:p = [1 2 3 0]; //表示 1*x^3+2*x^2+3*x^1+0 ,系数从高次向低次项,0系数不能省略. roots函数:求解多项式的根.roots(p ...

  3. STM32 C++编程 003 USART(串口)类

    使用 C++ 语言给 STM32 编写一个 Usart 类 我使用的STM32芯片:STM32F103ZET6 我们使用的STM32库版本:V3.5.0 注意: 想学习本套 STM32 C++编程 的 ...

  4. ROS Learning-001 安装 ROS indigo

    如何在 Ubuntu14.04 上安装 ROS indigo 我使用的虚拟机软件:VMware Workstation 11 使用的Ubuntu系统:Ubuntu 14.04.4 LTS ROS 版本 ...

  5. ZROI2018提高day5t3

    传送门 分析我们可以根据性质将这个序列构造成一个环:0,a[1~n],0,a[n~1] 这中间的0是为了起间隔作用的. 我们又知道b[i]=a[i-1]^a[i+1] c[i]=b[i-1]^b[i+ ...

  6. ZROI2018普转提day2t1

    传送门 分析 我们通过仔细研究不难发现对于一次交换(i,i+1)的操作之后,在i之前的点就不可能跑到i之后,i+1之后的的点也不可能跑到i+1之前,所以这个序列在一次交换之后就相当于被分成了两个部分. ...

  7. wrodcount

    PSP2.1 PSP阶段 预估耗时 (分钟) 实际耗时 (分钟) Planning 计划  20  20 · Estimate · 估计这个任务需要多少时间 20   20 Development 开 ...

  8. 十三周作业—使用Metaspoit攻击MS08-067

    操作过程及结果如下:

  9. C# Winform欢迎窗体实现()

    方法一.program.cs 中先启动欢迎窗体,然后注册程序运行空闲去执行主程序窗体相应初始化代码 static void Main(string[] args) { Application.Enab ...

  10. 正经学C#_委托

    以前不会,甚至连想去学都没想.啧啧啧,我是何等朽木啊. 我先不说其中理念,或者原理,咱就先说最简单的用法.怎么去使用委托. 委托 Delegate 使用委托,就要先定义一个委托.定义一个委托就要先声明 ...