【题解】 P5021赛道修建
【题解】P5021 赛道修建
二分加贪心,轻松拿省一(我没有QAQ)
题干有提示:
输出格式:
输出共一行,包含一个整数,表示长度最小的赛道长度的最大值。
注意到没,最小的最大值,还要多明显?
那么我们考虑二分。
直接二分答案,假设我们得到了二分答案\(x\),我们就利用这个答案检查是否可行。考虑这样的一种办法,指定一个点为树的根,先将\(dfs\)放下去,每个\(dfs\)都要尽量将这个节点内所有的赛道合成成满足\(\ge x\),并且贡献一条尽量长的赛道上去。假设有一个\(dfs\)表示自己有多于两条多出来的赛道,它们接起来不能满足条件,那么这个答案非法。
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<vector>
#include<set>
#include<map>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<bitset>
#include<ctime>
using namespace std;
#define TMP template < class ins >
#define endl '\n'
#define RP(t,a,b) for(register int t=(a),edd=(b);t<=edd;t++)
#define ERP(t,a) for(register int t=head[(a)];t;t=e[t].nx)
#define DRP(t,a,b) for(register int t=(a),edd=(b);t>=edd;t--)
#define more(a,b) (a)=(a)>(b)?(a):(b)
typedef long long ll;
TMP inline ins qr(ins tag) {
char c=getchar();
ins x=0;
int q=0;
while(c<48||c>57)
q=c==45?-1:q,c=getchar();
while(c>=48&&c<=57)
x=x*10+c-48,c=getchar();
return q==-1?-x:x;
}
const int maxn=50050;
struct E {
int to,w,nx;
} e[maxn<<1];
int head[maxn];
ll d[maxn];
int cnt;
inline void add(int fr,int to,int w,bool f) {
e[++cnt]=(E) {
to,w,head[fr]
};
head[fr]=cnt;
if(f)
add(to,fr,w,0);
}
int n,m;
ll ans;
ll cmp;
#define pb insert
multiset<ll> sav[maxn];
#define tor multiset<ll>::iterator
ll dfs(int now,int last) {
if(ans>=m)
return 0;
ERP(t,now) {
if(e[t].to!=last) {
ll temp=dfs(e[t].to,now)+e[t].w;
if(temp>=cmp)
ans++;
else
sav[now].pb(temp);
if(ans>=m)
return 0;
}
}
ll ret=0;
if(sav[now].size()==1)
return max(0ll,*sav[now].begin());
while(sav[now].size()) {
tor b=sav[now].begin();
tor k=sav[now].lower_bound(cmp-(*b));
if(k==sav[now].end()) {
more(ret,*b);
sav[now].erase(b);
continue;
}
if(k==b)
k++;
if(k==sav[now].end()) {
more(ret,*b);
sav[now].erase(b);
continue;
}
ans++;
if(ans>=m)
return 0;
if(k==b)
sav[now].erase(k);
else {
sav[now].erase(k);
sav[now].erase(b);
}
}
return ret;
}
inline bool chek(int x) {
RP(t,1,n)
sav[t].clear();
cmp=x;
ans=0;
dfs(1,0);
return ans>=m;
}
inline int eff(int rb) {
int lb=1,mid;
do {
mid=(lb+rb)>>1;
//cout<<rb<<' '<<mid<<' '<<lb<<endl;
if(chek(mid))
lb=mid+1;
else
rb=mid-1;
} while(lb<=rb);
return rb;
}
void predfs(int now,int last,int w) {
d[now]=d[last]+w;
ERP(t,now)
if(e[t].to!=last)
predfs(e[t].to,now,e[t].w);
}
int t1,t2,t3;
const int inf=0x3f3f3f3f;
inline void init() {
n=qr(1);
m=qr(1);
RP(t,1,n-1) {
t1=qr(1);
t2=qr(1);
t3=qr(1);
add(t1,t2,t3,1);
}
predfs(1,0,0);
ll sav=0,rem=-inf;
RP(t,1,n)
if(d[t]>rem)
sav=t,rem=d[t];
predfs(sav,0,0);
sav=0,rem=-inf;
RP(t,1,n)
if(d[t]>rem)
sav=t,rem=d[t];
cout<<eff(rem)<<endl;
}
signed main() {
#ifndef ONLINE_JUDGE
freopen("testdata.in","r",stdin);
freopen("out.out","w",stdout);
#endif
init();
return 0;
}
【题解】 P5021赛道修建的更多相关文章
- 二分答案 + multiset || NOIP 2018 D1 T3 || Luogu P5021 赛道修建
题面:P5021 赛道修建 题解:二分答案,用Dfs进行判断,multiset维护. Dfs(x,fa,Lim)用来计算以x为根的子树中有多少符合条件的路径,并返回剩余未使用的最长路径长. 贪心思想很 ...
- 竞赛题解 - NOIP2018 赛道修建
\(\mathcal {NOIP2018}\) 赛道修建 - 竞赛题解 额--考试的时候大概猜到正解,但是时间不够了,不敢写,就写了骗分QwQ 现在把坑填好了~ 题目 (Copy from 洛谷) 题 ...
- P5021 赛道修建[贪心+二分]
题目描述 C 城将要举办一系列的赛车比赛.在比赛前,需要在城内修建 mm 条赛道. C 城一共有 nn 个路口,这些路口编号为 1,2,-,n1,2,-,n,有 n-1n−1 条适合于修建赛道的双向通 ...
- P5021 赛道修建 题解
原题链接 简要题意: 在一棵树上求 \(m\) 条不相交的路径的最小值的最大值. 本题部分分很多,而且本人也交了 \(27\) 次,所以一定要仔细讲部分分! 算法一 对于 \(b_i = a_i + ...
- [NOIp2018] luogu P5021 赛道修建
我同学的歌 题目描述 你有一棵树,每条边都有权值 did_idi.现在要修建 mmm 条赛道,一条赛道是一条连贯的链,且一条边至多出现在一条赛道里.一条赛道的长被定义为,组成这条赛道的边的权值之和. ...
- P5021 赛道修建 (NOIP2018)
传送门 考场上把暴力都打满了,结果文件输入输出写错了.... 当时时间很充裕,如果认真想想正解是可以想出来的.. 问你 长度最小的赛道长度的最大值 显然二分答案 考虑如何判断是否可行 显然对于一个节点 ...
- 洛谷P5021 赛道修建
题目 首先考虑二分,然后发现最小长度越大的话,赛道就越少.所以可以用最终的赛道个数来判断长度是否合理.问题转化为给定一个长度,问最多有多少条互不重叠路径比这个给定长度大. 考虑贪心,毕竟贪心也是二分c ...
- 洛谷P5021 赛道修建 NOIp2018 贪心+二分答案
正解:贪心+LCA+二分答案 解题报告: 想先港下部分分qwq因为我部分分只拿到了10ptsQAQ(时间不够不是理由,其实还是太弱,所以要想很久,所以才时间不够QAQ m=1 找直径长度,完 一条链 ...
- 题解 NOIP2018【赛道修建】—— 洛谷
这道题有一点点树上dp的意思(大佬轻喷 我刚拿到这道题的时候毫无头绪,只知道这道题要二分答案 为什么是二分答案??? 题目: 目前赛道修建的方案尚未确定.你的任务是设计一 种赛道修建的方案,使得修建的 ...
随机推荐
- ubuntu归档管理器消失了?
Ubuntu - gnome 下的归档管理器软件名称: file-roller如果没有看看是不是这个包让你删除掉了?用这个命令查: dpkg -l | grep file-roller 如果有这 ...
- 七天学会ASP.NET MVC (四)——用户授权认证问题 【转】
http://www.cnblogs.com/powertoolsteam/p/MVC_four.html 小编应各位的要求,快马加鞭,马不停蹄的终于:七天学会 Asp.Net MVC 第四篇出炉,在 ...
- windows 屏幕坐标 窗口坐标 客户区坐标 逻辑坐标 设备坐标之间的关系及转换
设置坐标映射 (1)Windows坐标系统 Windows坐标系分为逻辑坐标系和设备坐标系两种,GDI支持这两种坐标系.一般而言, GDI的文本和图形输出函数使用逻辑坐标,而在客户区移动或按下鼠 ...
- Netty通过心跳保持长链接
Netty自带心跳检测功能,IdleStateHandler,客户端在写空闲时主动发起心跳请求,服务器接受到心跳请求后给出一个心跳响应.当客户端在一定时间范围内不能够给出响应则断开链接. public ...
- 知其一不知其二之Jenkins Hacking
转自安全脉搏 本文首发安全脉搏 感谢大王叫我来巡山 的投递 转载请注明来源 大多安全工作者听到jenkins都会知道有个未授权的命令执行 但是如果Script页面要授权才能访问呢 或者你的用户没有Ov ...
- CentOS7.1 KVM虚拟化之经常使用管理虚拟机命令(3)
一.查看虚拟机列表及状态 [root@kvm01 ~]# virsh list --all Id Name State ---------------------------------------- ...
- mixare的measureText方法在频繁调用时抛出“referencetable overflow max 1024”的解决方式
这几天在搞基于位置的AR应用,採用了github上两款开源项目: mixare android-argument-reality-framework 这两个项目实现机制大致同样.我选取的是androi ...
- Struts2学习五----------指定多个配置文件
© 版权声明:本文为博主原创文章,转载请注明出处 指定多个配置文件 - 在Struts2配置文件中使用include可指定多个配置文件 实例 1.项目结构 2.pom.xml <project ...
- Lua学习八----------Lua运算符
© 版权声明:本文为博主原创文章,转载请注明出处 1.Lua运算符: - 算术运算符:+(加法).-(减法).*(乘法)./(除法-取整).%(除法-取余).^(乘幂).-(负号) - 关系运算符:= ...
- Codeforces 309C Memory for Arrays 二进制模拟进位
题目链接:点击打开链接 题意: 给定n个箱子m个物品 以下n个数字表示箱子的容量 以下m个数字b1-bm 表示物品体积为2^bi大 问最多有多少个物品能够放入箱子. 思路: 贪心,先放小的,小的不能放 ...