P4292 [WC2010]重建计划
无脑上二分+淀粉质完事了
每个子树算的时候把儿子按照最长路径从小到大依次做,和前面的单调队列算一波,每个儿子的复杂度不超过这个子树大小
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define il inline
#define vd void
typedef long long ll;
il int gi(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n,L,R;
int fir[100010],dis[200010],nxt[200010],w[200010],id;
il vd link(int a,int b,int c){nxt[++id]=fir[a],fir[a]=id,dis[id]=b,w[id]=c;}
std::vector<std::pair<int,int> >G[100010];std::vector<int>Rt[100010];
int RT;
namespace build{
bool vis[100010];
int siz[100010],f[100010],N,rt;
il vd getrt(int x,int fa=-1){
siz[x]=1;f[x]=0;
for(int i=fir[x];i;i=nxt[i]){
if(dis[i]==fa||vis[dis[i]])continue;
getrt(dis[i],x);
siz[x]+=siz[dis[i]];
f[x]=std::max(f[x],siz[dis[i]]);
}
f[x]=std::max(f[x],N-siz[x]);
if(f[x]<f[rt])rt=x;
}
int maxl[100010];il bool cmp(const std::pair<int,int>&a,const std::pair<int,int>&b){return maxl[a.first]<maxl[b.first];}
il vd dfs(int x,int fa=-1){
maxl[x]=0;
for(int i=fir[x];i;i=nxt[i]){
if(dis[i]==fa||vis[dis[i]])continue;
dfs(dis[i],x);
maxl[x]=std::max(maxl[x],maxl[dis[i]]+1);
}
}
il vd build(int x){
vis[x]=1;
for(int i=fir[x];i;i=nxt[i])if(!vis[dis[i]])G[x].push_back(std::make_pair(dis[i],w[i]));
dfs(x);
std::sort(G[x].begin(),G[x].end(),cmp);
for(int i=0;i<G[x].size();++i){
rt=0;N=siz[G[x][i].first];getrt(G[x][i].first);
Rt[x].push_back(rt);build(rt);
}
}
il vd build(){
rt=0;f[0]=1e9;N=n;getrt(1);
RT=rt;build(rt);
}
}
double mid,res;
namespace dfz{
bool vis[100010];
double f[100010],g[100010];
int que[100010],hd,tl;
int N;
bool flg;
il vd dfs(int x,int fa=-1,int len=0,double sum=0){
if(N<len)g[N=len]=sum;
else g[len]=std::max(g[len],sum);
for(int i=fir[x];i;i=nxt[i]){
if(dis[i]==fa||vis[dis[i]])continue;
dfs(dis[i],x,len+1,sum+w[i]-mid);
}
}
il vd divide(int x){
vis[x]=1;int n=0;f[0]=0;
for(int i=0;i<G[x].size();++i){
N=0;g[0]=0;dfs(G[x][i].first,x,1,G[x][i].second-mid);
hd=tl=0;
for(int j=0,p=n;j<=N;++j){
while(~p&&p+j>=L){
while((hd^tl)&&f[que[tl-1]]<f[p])--tl;
que[tl++]=p--;
}
while((hd^tl)&&que[hd]+j>R)++hd;
if((hd^tl)&&f[que[hd]]+g[j]>0){flg=1;return;}
}
for(int i=0;i<=n;++i)f[i]=std::max(f[i],g[i]);
for(int i=n+1;i<=N;++i)f[i]=g[i];
n=N;
}
for(int i=0;i<Rt[x].size();++i){
divide(Rt[x][i]);
if(flg)return;
}
}
il vd clear(){flg=0;memset(vis,0,sizeof vis);}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
n=gi(),L=gi(),R=gi();
int a,b,c;for(int i=1;i<n;++i)a=gi(),b=gi(),c=gi(),link(a,b,c),link(b,a,c);
build::build();
double l=1,r=1000000;
while(r-l>1e-4){
mid=(l+r)*0.5;
dfz::clear();
dfz::divide(RT);
if(dfz::flg)l=mid;
else r=mid;
}
l=(l+r)*0.5;printf("%.3lf\n",l);
return 0;
}
P4292 [WC2010]重建计划的更多相关文章
- 洛谷 P4292 [WC2010]重建计划 解题报告
P4292 [WC2010]重建计划 题目描述 \(X\)国遭受了地震的重创, 导致全国的交通近乎瘫痪,重建家园的计划迫在眉睫.\(X\)国由\(N\)个城市组成, 重建小组提出,仅需建立\(N-1\ ...
- 并不对劲的bzoj1758:p4292:[WC2010]重建计划
题目大意 \(n\)(\(n\leq10^5\))个点的一棵树,有边权\(w\),给定\(l,r\),求边数在\([l,r]\)中的路径的平均边权的最大值 题解 二分答案,判断时将边权变成\(w-mi ...
- BZOJ 1758 / Luogu P4292 [WC2010]重建计划 (分数规划(二分/迭代) + 长链剖分/点分治)
题意 自己看. 分析 求这个平均值的最大值就是分数规划,二分一下就变成了求一条长度在[L,R]内路径的权值和最大.有淀粉质的做法但是我没写,感觉常数会很大.这道题可以用长链剖分做. 先对树长链剖分. ...
- P4292 [WC2010]重建计划 点分治+单调队列
题目描述 题目传送门 分析 看到比值的形式就想到 \(01分数规划\),二分答案 设当前的值为 \(mids\) 如果存在\(\frac{\sum _{e \in S} v(e)}{|S|} \geq ...
- 洛谷 P4292 - [WC2010]重建计划(长链剖分+线段树)
题面传送门 我!竟!然!独!立!A!C!了!这!道!题!incredible! 首先看到这类最大化某个分式的题目,可以套路地想到分数规划,考虑二分答案 \(mid\) 并检验是否存在合法的 \(S\) ...
- BZOJ1758: [Wc2010]重建计划
题解: 这题我居然做了一星期?... 平均值的极值其实也可以算是一种分数规划,只不过分母上b[i]=1 然后我们就可以二分这个值.类似与 HNOI最小圈 如果没有 链的长度的限制的话,我们直接两遍df ...
- [WC2010]重建计划 长链剖分
[WC2010]重建计划 LG传送门 又一道长链剖分好题. 这题写点分治的人应该比较多吧,但是我太菜了,只会长链剖分. 如果你还不会长链剖分的基本操作,可以看看我的长链剖分总结. 首先一看求平均值最大 ...
- bzoj 1758 [Wc2010]重建计划 分数规划+树分治单调队列check
[Wc2010]重建计划 Time Limit: 40 Sec Memory Limit: 162 MBSubmit: 4345 Solved: 1054[Submit][Status][Disc ...
- bzoj 1758: [Wc2010]重建计划
Description Input 第 一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案 ...
随机推荐
- PC客户端开发细节记录:保存GUID到VARIANT
有两个 API 可以实现保存 GUID 到 VARIANT InitVariantFromGUIDAsBuffer 以字节数组形式保存,保存类型为 VT_ARRAY | VT_UI1,相当于字节拷贝, ...
- 安卓ADB命令
查看连接的设备 adb devices -l FastBoot常用命令: fastboot erase system #擦除system分区 fastboot erase boot #擦除 ...
- 文档撰写思路与排版(hadoop)
这几天在写项目提交的几个报告,写完回想了一下,在写作框架确定与排版上浪费了不少时间,特此总结一下思路. 这个写完回家过年了....emmmm 1. 定好大标题框架,使用自动添加序号,先不着急修改样式 ...
- 关于npm run build打包后css样式中的图片失效的问题(如background)
平时run dev都能正常显示的css背景图片在npm run build打包后竟然不显示了(写在标签对中的图片都可以正常显示),而且dist/static/img目录下是确实有这张图片的,于是查看打 ...
- Beyond Compare 4 使用方法
一 : 二 : 三 :
- android kl文件
android kl(key layout)文件是一个映射文件,是标准linux与anroid的键值映射文件,kl文件可以有很多个,但是它有一个使用优先级: /system/usr/keylayout ...
- python基础学习4----元组
元组又叫只读列表,不可以修改其内容 1.创建元组 tuple1=(1,3,2,4,5) tuple2=()#空元组 tuple3=('a',) #元组中只有一个元素时要在元素后面加上逗号,否则会被当成 ...
- python set集合一些基本方法
set集合是一个无序且不重复的元素集合 这个数据类型没有重复的,而且也没有顺序 一些基本的方法: 添加元素 s1 = {11, 22, 33} s1.add(123)#添加一个新的元素 print(s ...
- docker18.ce harbor 安装
Harbor 是什么? harbor VMware 开发的一个容器镜像仓库,harbor的功能提供用户权限管理.镜像复制等功能,提高使用的registry的效率. 安装最新版的docker可以参考d ...
- C# 利用VS自带的WSDL工具生成WebService服务类(转载)
WebService有两种使用方式,一种是直接通过添加服务引用,另一种则是通过WSDL生成. 添加服务引用大家基本都用过,这里就不讲解了. 那么,既然有直接引用的方式,为什么还要通过WSDL生成呢? ...