【题解】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赛道修建的更多相关文章

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

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

  2. 竞赛题解 - NOIP2018 赛道修建

    \(\mathcal {NOIP2018}\) 赛道修建 - 竞赛题解 额--考试的时候大概猜到正解,但是时间不够了,不敢写,就写了骗分QwQ 现在把坑填好了~ 题目 (Copy from 洛谷) 题 ...

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

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

  4. P5021 赛道修建 题解

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

  5. [NOIp2018] luogu P5021 赛道修建

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

  6. P5021 赛道修建 (NOIP2018)

    传送门 考场上把暴力都打满了,结果文件输入输出写错了.... 当时时间很充裕,如果认真想想正解是可以想出来的.. 问你 长度最小的赛道长度的最大值 显然二分答案 考虑如何判断是否可行 显然对于一个节点 ...

  7. 洛谷P5021 赛道修建

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

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

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

  9. 题解 NOIP2018【赛道修建】—— 洛谷

    这道题有一点点树上dp的意思(大佬轻喷 我刚拿到这道题的时候毫无头绪,只知道这道题要二分答案 为什么是二分答案??? 题目: 目前赛道修建的方案尚未确定.你的任务是设计一 种赛道修建的方案,使得修建的 ...

随机推荐

  1. noip2017集训测试赛(六)Problem A: 炮艇大赛之正式赛

    题目描述 给定一个长度为\(L \le 10^9\)的环形赛道, \(n \le 10^5\)个人在上面赛艇. 每个人的速度都不相同, 假如为正则顺时针走, 否则逆时针走. 当两个人相遇时, 他们就会 ...

  2. 2016北京集训测试赛(十七)Problem C: 数组

    Solution 线段树好题. 我们考虑用last[i]表示\(i\)这个位置的颜色的上一个出现位置. 考虑以一个位置\(R\)为右端点的区间最远能向左延伸到什么位置: \(L = \max_{i \ ...

  3. 用NSLogger代替NSLog输出调试信息

    安装 NSLogger分为两部分,LoggerClient和NSLogger Viewer,你的App需要导入前者,后者是一个独立的mac应用,NSLogger所有的调试信息将输出到这个应用中. 安装 ...

  4. SQLITE3 --详解

    由于我主要负责我们小组项目数据库模块的部分所以这几天都一直在研究在iphone中最为常用的一个简单数据库sqlite,自己也搜集很多资料,因此在 这里总结一下这几天的学习成果: Sqlite 操作简明 ...

  5. 从Android动画到贝塞尔曲线

    基础知识: 动画通过连续播放一系列画面,给视觉造成连续变化的图画.很通俗的一种解释.也很好理解.那么我们先来一个案例看看. 动画案例:百度贴吧小熊奔跑 效果: topic.gif 代码: <?x ...

  6. Git修改IP重新定位的方法

    进入已clone项目的.git文件夹,打开config文件 打开config,如图显示,修改url中的IP为192.168.6.102,然后保存 在项目上右击选择属性(R),然后选择Git,即可看到当 ...

  7. BZOJ 1878 SDOI2009 HH的项链 树状数组/莫队算法

    题目大意:给定一个序列.求一个区间内有多少个不同的数 正解是树状数组 将全部区间依照左端点排序 然后每次仅仅统计左端点開始的每种颜色的第一个数即可了 用树状数组维护 我写的是莫队算法 莫队明显能搞 m ...

  8. mysql莫名的主键重复

    REPAIR TABLE t_car_type; OPTIMIZE TABLE t_car_type; 可解决问题

  9. VELT-0.1.5开发:在VS2013下进行python开发

    快乐虾 http://blog.csdn.net/lights_joy/(QQ群:Visual EmbedLinux Tools 375515651) 欢迎转载,但请保留作者信息 本文仅适用于vs20 ...

  10. IOS知识点收集

    17  duplicate symbols for architecture armv7s 用cocoapods 的时候出现,这种错误一般是由重复引用库文件引起. 原因:自己尝试添加Reachabil ...