Description

Input

第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai,Bi,Vi分别表示道路(Ai,Bi),其价值为Vi 其中城市由1..N进行标号

Output

输出最大平均估值,保留三位小数

Sample Input

4
2 3
1 2 1
1 3 2
1 4 3

Sample Output

2.500

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]重建计划的更多相关文章

  1. BZOJ1758: [Wc2010]重建计划

    题解: 这题我居然做了一星期?... 平均值的极值其实也可以算是一种分数规划,只不过分母上b[i]=1 然后我们就可以二分这个值.类似与 HNOI最小圈 如果没有 链的长度的限制的话,我们直接两遍df ...

  2. bzoj1758 [Wc2010]重建计划 & bzoj2599 [IOI2011]Race

    两题都是树分治. 1758这题可以二分答案avgvalue,因为avgvalue=Σv(e)/s,因此二分后只需要判断Σv(e)-s*avgvalue是否大于等于0,若大于等于0则调整二分下界,否则调 ...

  3. BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP

    题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...

  4. [BZOJ1758][WC2010]重建计划(点分治+单调队列)

    点分治,对于每个分治中心,考虑求出经过它的符合长度条件的链的最大权值和. 从分治中心dfs下去取出所有链,为了防止两条链属于同一个子树,我们一个子树一个子树地处理. 用s1[i]记录目前分治中心伸下去 ...

  5. BZOJ1758: [Wc2010]重建计划(01分数规划+点分治+单调队列)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1758 01分数规划,所以我们对每个重心进行二分.于是问题转化为Σw[e]-mid>=0, ...

  6. BZOJ1758 WC2010 重建计划 二分答案、点分治、单调队列

    传送门 看到平均数最大,自然地想到二分答案.那么我们的$check$函数就是要求:是否存在一条长度在$[L,U]$的路径,满足其权值和$\geq 0$. 看到长度在$[L,U]$,自然地想到点分治求解 ...

  7. 2019.01.21 bzoj1758: [Wc2010]重建计划(01分数规划+长链剖分+线段树)

    传送门 长链剖分好题. 题意简述:给一棵树,问边数在[L,R][L,R][L,R]之间的路径权值和与边数之比的最大值. 思路: 用脚指头想都知道要01分数规划. 考虑怎么checkcheckcheck ...

  8. 洛谷 P4292 [WC2010]重建计划 解题报告

    P4292 [WC2010]重建计划 题目描述 \(X\)国遭受了地震的重创, 导致全国的交通近乎瘫痪,重建家园的计划迫在眉睫.\(X\)国由\(N\)个城市组成, 重建小组提出,仅需建立\(N-1\ ...

  9. [WC2010]重建计划 长链剖分

    [WC2010]重建计划 LG传送门 又一道长链剖分好题. 这题写点分治的人应该比较多吧,但是我太菜了,只会长链剖分. 如果你还不会长链剖分的基本操作,可以看看我的长链剖分总结. 首先一看求平均值最大 ...

  10. bzoj 1758 [Wc2010]重建计划 分数规划+树分治单调队列check

    [Wc2010]重建计划 Time Limit: 40 Sec  Memory Limit: 162 MBSubmit: 4345  Solved: 1054[Submit][Status][Disc ...

随机推荐

  1. 使用微服务架构思想,设计部署OAuth2.0授权认证框架

    1,授权认证与微服务架构 1.1,由不同团队合作引发的授权认证问题 去年的时候,公司开发一款新产品,但人手不够,将B/S系统的Web开发外包,外包团队使用Vue.js框架,调用我们的WebAPI,但是 ...

  2. 大数据小视角1:从行存储到RCFile

    前段时间一直在忙碌写毕设与项目的事情,很久没有写一些学习心得与工作记录了,开了一个新的坑,希望能继续坚持写作与记录分布式存储相关的知识.为什么叫小视角呢?因为属于随想型的内容,可能一个由小的视角来审视 ...

  3. 有关Java 锁原理

    锁 锁是用来锁东西的,让别人打不开也看不到!在线程中,用这个“锁”隐喻来说明一个线程在“操作”一个目标(如一个变量)的时候,如果变量是被锁住的,那么其他线程就对这个目标既“操作”不了(挂起)也无法看到 ...

  4. Django的时区问题

    在Django项目中,最好全部日期值都做成配时区信息的,但是由于遗留项目或者跨语言项目,其他语言的开发人员觉得时区信息处理太麻烦.如何在一个项目中同时适配带时区和不带时区的两种字段. 1.输出:不带时 ...

  5. python做量化交易干货分享

    http://www.newsmth.NET/nForum/#!article/Python/128763 最近程序化交易很热,量化也是我很感兴趣的一块. 国内量化交易的平台有几家,我个人比较喜欢用的 ...

  6. 深入理解javascript 匿名函数和闭包

    代码如下: (function(){ //这里忽略jQuery所有实现 })(); (function(){ //这里忽略jQuery所有实现 })();  半年前初次接触jQuery的时候,我也像其 ...

  7. java ArrayList集合

    ArrayList集合是程序中最常见的一种集合,它属于引用数据类型(类).在ArrayList内部封装了一个长度可变的数组,当存入的元素超过数组长度时,ArrayList会在内存中分配一个更大的数组来 ...

  8. Spring Boot常用注解总结

    Spring Boot常用注解总结 @RestController和@RequestMapping注解 @RestController注解,它继承自@Controller注解.4.0之前的版本,Spr ...

  9. 几张图帮你理解 docker 基本原理及快速入门

    写的非常好的一篇文章,不知道为什么被删除了.  利用Google快照,做个存档. 快照地址:地址 作者地址:青牛 什么是docker Docker 是一个开源项目,诞生于 2013 年初,最初是 do ...

  10. 检测磁盘驱动的健康程度SMART

    在linux中,工具包的名字为smartmontools 在CentOS中可以使用 yum install smartmontools来安装工具 首先通过smartctl -i /dev/sda 来检 ...