【bzoj1758】[Wc2010]重建计划
Description

Input
第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai,Bi,Vi分别表示道路(Ai,Bi),其价值为Vi 其中城市由1..N进行标号
Output
输出最大平均估值,保留三位小数
Sample Input
2 3
1 2 1
1 3 2
1 4 3
Sample Output
HINT
N<=100000,1<=L<=U<=N-1,Vi<=1000000 新加数据一组 By leoly,但未重测..2016.9.27
题解:
好一个扫把树……长见识长见识。
显然二分答案+树的点分治。每次遍历一棵子树来得到$dis$数组,表示同一路径数的最大权值,然后再存一个之前遍历子树的桶,含义与$dis$一样,但是要注意从小到大处理每棵子树。扫把树……卡死人。
顺便一提,bzoj不会爆栈。
(空行比较多,所以显得很长……)
#define Troy 09/30/2017 #define inf 0x7fffffff #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=;
const double eps=1e-; inline int read(){
int s=,k=;char ch=getchar();
while(ch<''|ch>'') ch=='-'?k=-:,ch=getchar();
while(ch>&ch<='') s=s*+(ch^),ch=getchar();
return s*k;
} struct edges{
int v;ll w;edges *last;
}edge[N<<],*head[N];int cnt; inline void push(int u,int v,ll w){
edge[++cnt]=(edges){v,w,head[u]};head[u]=edge+cnt;
} int n,up,low,tot,top,root,size[N],heavy[N],T[N],Tdis[N],part,from;
ll t[N],dis[N];
bool vis[N];
double ans,maxr; inline void dfs(int x,int fa,int deep){
size[x]=;
heavy[x]=;
for(edges *i=head[x];i;i=i->last)if(i->v!=fa&&(!vis[i->v])){
dfs(i->v,x,deep+);
size[x]+=size[i->v];
heavy[x]=max(size[i->v],heavy[x]);
}
heavy[x]=max(heavy[x],tot-size[x]);
if(heavy[x]<top)
top=heavy[x],root=x;
} inline void calc(int x,int fa,ll d,int lens){
if(lens>up) return ;
if(Tdis[lens]!=part){
Tdis[lens]=part;
dis[lens]=d;
}else
dis[lens]=max(dis[lens],d);
for(edges *i=head[x];i;i=i->last) if(i->v!=fa&&(!vis[i->v])){
calc(i->v,x,d+i->w,lens+);
}
} inline void get_new(int x,int fa,ll d,int lens){
if(lens>up) return;
if(T[lens]!=T[])
T[lens]=T[],t[lens]=d;
else
t[lens]=max(t[lens],d);
from=max(from,lens);
for(edges *i=head[x];i;i=i->last) if(i->v!=fa&&(!vis[i->v])){
get_new(i->v,x,d+i->w,lens+);
}
} int q[N];
double nq[N]; inline bool Judge(double x){
int l=,r=;
int pos=min(up-,from);
bool flag=;
while(pos>=low){
if(T[pos]!=T[]){
pos--;continue;
}
while(r>l&&nq[r-]<t[pos]-x*pos)
r--;
nq[r]=t[pos]-x*pos;
q[r++]=pos;
pos--;
}
for(int i=low-pos;i<=up;i++){
if(Tdis[i]!=part) break;
if(pos>=&&i+pos>=low&&T[pos]==T[]){
while(r>l&&nq[r-]<t[pos]-x*pos)
r--;
nq[r]=t[pos]-x*pos;
q[r++]=pos;
}
while(l<r&&q[l]+i>up)
l++;
pos--;
if(l<r&&nq[l]+dis[i]-i*x>=)
return true;
}
return false;
} struct node{
int v,w;
friend bool operator <(node x,node y){
return size[x.v]<size[y.v];
}
}sons[N]; inline void solve(int u){
tot=size[u];
top=inf;
dfs(u,u,);
vis[root]=true;
T[]++;
from=;
int cc=;
for(edges *i=head[root];i;i=i->last)if(!vis[i->v]){
cc++;
sons[cc].v=i->v;
sons[cc].w=i->w;
}
sort(sons+,sons++cc);
for(int i=;i<=cc;i++){
if(i>){
part++;
calc(sons[i].v,,sons[i].w,);
double l=ans,r=maxr,mid;
while(l<r-eps){
mid=(l+r)/;
if(Judge(mid)) l=mid;
else r=mid;
}
ans=l;
}
if(i<cc)
get_new(sons[i].v,,sons[i].w,);
}
for(edges *i=head[root];i;i=i->last) if(!vis[i->v])
solve(i->v);
} int main(){
n=read();
low=read(),up=read();
for(int i=,u,v,w;i<n;i++){
u=read(),v=read(),w=read();
push(u,v,w),push(v,u,w);
maxr=max(maxr,w+0.0);
}
size[]=n;
solve();
printf("%.3lf\n",ans);
}
【bzoj1758】[Wc2010]重建计划的更多相关文章
- BZOJ1758: [Wc2010]重建计划
题解: 这题我居然做了一星期?... 平均值的极值其实也可以算是一种分数规划,只不过分母上b[i]=1 然后我们就可以二分这个值.类似与 HNOI最小圈 如果没有 链的长度的限制的话,我们直接两遍df ...
- bzoj1758 [Wc2010]重建计划 & bzoj2599 [IOI2011]Race
两题都是树分治. 1758这题可以二分答案avgvalue,因为avgvalue=Σv(e)/s,因此二分后只需要判断Σv(e)-s*avgvalue是否大于等于0,若大于等于0则调整二分下界,否则调 ...
- BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP
题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...
- [BZOJ1758][WC2010]重建计划(点分治+单调队列)
点分治,对于每个分治中心,考虑求出经过它的符合长度条件的链的最大权值和. 从分治中心dfs下去取出所有链,为了防止两条链属于同一个子树,我们一个子树一个子树地处理. 用s1[i]记录目前分治中心伸下去 ...
- BZOJ1758: [Wc2010]重建计划(01分数规划+点分治+单调队列)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1758 01分数规划,所以我们对每个重心进行二分.于是问题转化为Σw[e]-mid>=0, ...
- BZOJ1758 WC2010 重建计划 二分答案、点分治、单调队列
传送门 看到平均数最大,自然地想到二分答案.那么我们的$check$函数就是要求:是否存在一条长度在$[L,U]$的路径,满足其权值和$\geq 0$. 看到长度在$[L,U]$,自然地想到点分治求解 ...
- 2019.01.21 bzoj1758: [Wc2010]重建计划(01分数规划+长链剖分+线段树)
传送门 长链剖分好题. 题意简述:给一棵树,问边数在[L,R][L,R][L,R]之间的路径权值和与边数之比的最大值. 思路: 用脚指头想都知道要01分数规划. 考虑怎么checkcheckcheck ...
- 洛谷 P4292 [WC2010]重建计划 解题报告
P4292 [WC2010]重建计划 题目描述 \(X\)国遭受了地震的重创, 导致全国的交通近乎瘫痪,重建家园的计划迫在眉睫.\(X\)国由\(N\)个城市组成, 重建小组提出,仅需建立\(N-1\ ...
- [WC2010]重建计划 长链剖分
[WC2010]重建计划 LG传送门 又一道长链剖分好题. 这题写点分治的人应该比较多吧,但是我太菜了,只会长链剖分. 如果你还不会长链剖分的基本操作,可以看看我的长链剖分总结. 首先一看求平均值最大 ...
- bzoj 1758 [Wc2010]重建计划 分数规划+树分治单调队列check
[Wc2010]重建计划 Time Limit: 40 Sec Memory Limit: 162 MBSubmit: 4345 Solved: 1054[Submit][Status][Disc ...
随机推荐
- 理解java值传递与引用传递
1.基本类型和引用类型在内存中的保存 Java中数据类型分为两大类,基本类型和对象类型.相应的,变量也有两种类型:基本类型和引用类型.基本类型的变量保存原始值,即它代表的值就是数值本身:而引用类型的变 ...
- 前端iFrame跨域问题
一.父域访问子域的元素 项目需求: iFrame是个聊天窗口,要求聊天窗口中点击图片图标,在父域将内容展示出来. 解决方法:(jQuery) 首先/要等iFrame加载完再执行函数!(代码如下) va ...
- java泛型应用实例 - 自定义泛型类,方法
近 短时间需要使用泛型,就研究了下,发现网上的问关于泛型的文章都是讲原理的, 很少有提到那里用泛型比较合适, 本文就泛型类和泛型方法的使用给出两 个典型应用场景. 例如一个toString的泛型方法, ...
- Http持久连接与HttpClient连接池
一.背景 HTTP协议是无状态的协议,即每一次请求都是互相独立的.因此它的最初实现是,每一个http请求都会打开一个tcp socket连接,当交互完毕后会关闭这个连接. HTTP协议是全双工的协议, ...
- 洛谷P1919 【模板】A*B Problem升级版 题解(FFT的第一次实战)
洛谷P1919 [模板]A*B Problem升级版(FFT快速傅里叶) 刚学了FFT,我们来刷一道模板题. 题目描述 给定两个长度为 n 的两个十进制数,求它们的乘积. n<=100000 如 ...
- 在Windows上安装FFmpeg程序的方法(you-get下载视频必备程序)
FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.它提供了录制.转换以及流化音视频的完整解决方案.它包含了非常先进的音频/视频编解码库libavcodec. 该程序 ...
- java解析XML文件四种方法之引入源文件
1.DOM解析(官方) try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); Documen ...
- kaggle入门项目:Titanic存亡预测(二)数据处理
原kaggle比赛地址:https://www.kaggle.com/c/titanic 原kernel地址:A Data Science Framework: To Achieve 99% Accu ...
- 利用Hive分析nginx日志
这里用到的nginx日志是网站的访问日志,比如日志格式: 180.173.250.74 - - [08/Jan/2015:12:38:08 +0800] "GET /avatar/xxx.p ...
- android获取手机机型、厂商、deviceID基本信息
/** * 系统工具类 */ public class SystemUtil { /** * 获取当前手机系统语言. * * @return 返回当前系统语言.例如:当前设置的是"中文-中国 ...