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. 万水千山ABP - 系统发布后迁移 CodeFirst 数据库[原创]

    在项目开发的过程中,常会遇到项目发布后还变更数据库的情况.这时如何方便地进行数据库迁移呢 ? 下面直接列出操作的步骤: 1. 发布修改后的应用: 将最新版本的应用更新到目标机器中.更新的文件当然不包括 ...

  2. Spring3 MVC使用@ResponseBody的乱码问题及解决办法

    近日用Spring3的MVC写东西,深感其之于Webwork/Struts2的便利,但是在通过@ResponseBody这个annotation输出一个json字符串的时候,发现页面上获得的json字 ...

  3. java中内存的使用

    一个java运行起来执行代码,主要的内存消耗有这几块: 1.堆 2.栈 :栈是每个线程一个的,是以消耗的内存是内存大小*线程数,当线程数特多时候需要小心 . 3.直接内存:主要是通道时候的缓存,在内存 ...

  4. git 使用简易指南

  5. 快速开发框架,及库存管理系统,基于easyui框架和C#语言MVC、EntityFrameWork、T4模板技术。

    快速开发框架,及库存管理系统,基于easyui框架和C#语言MVC.EntityFrameWork.T4模板技术. 产品界面如下图所示: 源码结构: 开放全部源码,如有需要请联系,QQ:1107141 ...

  6. Kali学习笔记4:Wireshark详细使用方法

    Kali Linux自带Wireshark工具使用介绍: 1.进入界面 这里Lua脚本报错,无需关注 开始使用: 双击第一个eth0:以太网0,开始抓包: 点击上边的这个按钮可以设置: 这里注意:需要 ...

  7. php 微信JS-SDK封装类

    JSSDK使用步骤: 步骤一:绑定域名 步骤二:引入JS文件 步骤三:通过config接口注入权限验证配置 步骤四:通过ready接口处理成功验证 步骤五:通过error接口处理失败验证 具体步骤方法 ...

  8. 基于reflectasm打造自己的通用bean工具

    业务场景: 在很多的业务系统中,erp,crm系统中,有许多的对象信息都是拆开来的,例如一个商品,那可能他的商品名称,商品等主要信息放在一个表(衍生出来一个对象),他的附属信息(商品图片,规格,价格等 ...

  9. NGINX按天生成日志文件的简易配置

    NGINX按天生成日志文件的简易配置 0x01 最近后端童鞋遇到一个小需求,拆分nginx生成的log文件,最好是按天生成,看着她还有很多bug待改的状态,我说这个简单啊,我来吧.曾经搞node后端的 ...

  10. STL-Map 源码剖析

    G++ ,cygnus\cygwin-b20\include\g++\stl_map.h 完整列表 /* * * Copyright (c) 1994 * Hewlett-Packard Compan ...