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. int类型被强制转换成较低精度的byte类型

    公司的项目上线之前会进行代码合规性检查,其中很容易违反的一个规则就是“不要把原始类型转换成较低的精度”,实际开发的过程中,很多方法在处理数据时,尤其在做移位操作的时候,难免要把int类型转换成byte ...

  2. Xshell 链接 Could not connect to '192.168.80.129' (port 22): Connection failed

    在使用Xshell链接虚拟机VM里面的Linux的时候.链接失败,报 Could not connect to ): Connection failed 解决步骤: 1.重启VM.Linux.Xshe ...

  3. javaScript(1)---概述

    javaScript(1)---概述 学习要点: 1.什么是JavaScript 2.JavaScript特点 3.JavaScript历史 4.JavaScript核心 JavaScript诞生于1 ...

  4. vue-cli目录结构

  5. java.lang.SecurityException: Can't make field constructor accessible

    原本使用GsonConvertor,在Android版本5.1.1上没有任何问题,结果切换到版本6.0.1上,出现以下所示问题: java.lang.IllegalArgumentException: ...

  6. Neo4j安装后的密码修改

    首先默认用户名/密码是neo4j/neo4j. 在安全验证打开的时候,你访问服务器/db/data之类的地址可能会提示您以下信息: { "password_change" : &q ...

  7. Django升级1.9.6出现的中文本地化bug

    Error日志: Error opening file for reading: Permission denied ERROR Internal Server Error: / Traceback  ...

  8. lodash中Collection部分所有方法的总结

    总结一下lodash中Collection的所有的方法,方便对比记忆,也便于使用时候查找. 1.    判断是否符合条件:返回bool: a)  every: 判断每一值是不是都符合条件: 通过 pr ...

  9. Java并发-对象共享

    我们不仅希望防止某个线程正在使用对象状态而其他的线程正在修改该状态,而且希望当一个线程修改了对象状态后,其他的线程能够看到发生的状态变化. 可见性:当读操作和写操作在不同的线程中进行时,他们的动作是共 ...

  10. python爬虫入门(八)Scrapy框架之CrawlSpider类

    CrawlSpider类 通过下面的命令可以快速创建 CrawlSpider模板 的代码: scrapy genspider -t crawl tencent tencent.com CrawSpid ...