点分治,对于每个分治中心,考虑求出经过它的符合长度条件的链的最大权值和。

从分治中心dfs下去取出所有链,为了防止两条链属于同一个子树,我们一个子树一个子树地处理。

用s1[i]记录目前分治中心伸下去的链中长度为i的链的最大权值,s2[i]记录新子树中的链的最大权值。

分数规划,考虑合并,枚举长度,由于另一个长度在一个滑动窗口中,所以使用单调队列求解即可。

为了保证复杂度,讲子树按高度排序。注意初始化等问题。

 #include<cstdio>
#include<vector>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
#define For(i,x) for (int i=h[x],k; i; i=nxt[i])
using namespace std; const int N=;
const double eps=1e-,inf=1e9;
bool vis[N];
int n,L,R,u,v,w,S,rt,tot,sz[N],f[N],he[N],d[N],q[N];
int cnt,h[N],pre[N],to[N<<],val[N<<],nxt[N<<];
double ans,dis[N],s1[N],s2[N];
vector<int>ve;
void add(int u,int v,int w){ to[++cnt]=v; val[cnt]=w; nxt[cnt]=h[u]; h[u]=cnt; } bool cmp(int a,int b){ return he[a]<he[b]; } void get(int x,int fa){
sz[x]=; f[x]=;
For(i,x) if ((k=to[i])!=fa && !vis[k])
get(k,x),f[x]=max(f[x],sz[k]),sz[x]+=sz[k];
f[x]=max(f[x],S-sz[x]);
if (f[x]<f[rt]) rt=x;
} void dfs(int x,int fa){
d[x]=d[fa]+; he[x]=;
For(i,x) if ((k=to[i])!=fa && !vis[k])
pre[k]=val[i],dfs(k,x),he[x]=max(he[x],he[k]+);
} void dfs2(int x,int fa,double mid){
dis[x]=dis[fa]+pre[x]-mid; s2[d[x]]=max(s2[d[x]],dis[x]);
For(i,x) if ((k=to[i])!=fa && !vis[k]) dfs2(k,x,mid);
} bool jud(double mid){
double res=-inf;
rep(i,,tot){
int k=ve[i],st=,ed=; dis[rt]=;
rep(j,,he[k]) s2[j]=-inf; dfs2(k,rt,mid);
rep(j,,he[k]){
if (st<=ed && q[st]>R-j) st++;
if (L-j<=he[k]){
while (st<=ed && s1[q[ed]]<s1[L-j]) ed--;
q[++ed]=L-j;
}
if (st<=ed) res=max(res,s1[q[st]]+s2[j]);
}
rep(j,,he[k]) s1[j]=max(s1[j],s2[j]);
}
return res>;
} void solve(int x){
vis[x]=; d[]=-; dfs(x,); dis[x]=; ve.clear();
For(i,x) if (!vis[k=to[i]]) ve.push_back(k=to[i]);
tot=ve.size()-;
if (tot==-) return;
sort(ve.begin(),ve.end(),cmp);
int ed=he[ve[tot]];
double L=ans,R=1e6;
while (L+eps<R){
double mid=(L+R)/;
rep(i,,ed) s1[i]=-inf; s1[]=;
if (jud(mid)) L=mid; else R=mid;
}
ans=max(ans,L);
For(i,x) if (!vis[k=to[i]]) rt=,S=sz[k],get(k,x),solve(rt);
} int main(){
freopen("bzoj1758.in","r",stdin);
freopen("bzoj1758.out","w",stdout);
scanf("%d%d%d",&n,&L,&R);
rep(i,,n) scanf("%d%d%d",&u,&v,&w),add(u,v,w),add(v,u,w);
f[]=n+; S=n; rt=; get(,);
solve(rt); printf("%.3lf\n",ans);
return ;
}

[BZOJ1758][WC2010]重建计划(点分治+单调队列)的更多相关文章

  1. P4292 [WC2010]重建计划 点分治+单调队列

    题目描述 题目传送门 分析 看到比值的形式就想到 \(01分数规划\),二分答案 设当前的值为 \(mids\) 如果存在\(\frac{\sum _{e \in S} v(e)}{|S|} \geq ...

  2. BZOJ1758: [Wc2010]重建计划

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. BZOJ.1758.[WC2010]重建计划(分数规划 点分治 单调队列/长链剖分 线段树)

    题目链接 BZOJ 洛谷 点分治 单调队列: 二分答案,然后判断是否存在一条长度在\([L,R]\)的路径满足权值和非负.可以点分治. 对于(距当前根节点)深度为\(d\)的一条路径,可以用其它子树深 ...

随机推荐

  1. Android选择头像

    http://www.jianshu.com/p/8b3e78046c1c 注意:在Android6.0之后,使用相机拍照需要权限 在选择头像使用相机拍摄时添加以下代码即可. Acp.getInsta ...

  2. [转]ROS(Robot Operating System)常用环境变量介绍

    本文简单介绍ROS系统中常用的环境变量用途及设置方式.ROS系统环境中除了必须配置的环境变量以外,其他的也是十分有用,通过修改变量路径,可以设置ROS系统中log文件存放路径,单元测试结果存放路径等. ...

  3. 2016.6.19——C++杂记

    C++杂记 补充的小知识点: 1.while(n--)和while(--n)区别: while(n--)即使不满足也执行一次循环后跳出. while(--n)不满足直接跳出循环,不执行语句. 用cou ...

  4. 2016.5.18——Excel Sheet Column Number

    Excel Sheet Column Number 本题收获: 1.对于字符串中字母转为ASIIC码:string s ;res = s[i]-'A'; 这个res就是数字s[i]-'A'是对ASII ...

  5. 20165230 2017-2018-2 《Java程序设计》第9周学习总结

    20165230 2017-2018-2 <Java程序设计>第9周学习总结 教材学习内容总结 第十二章 java网络编程 学习了用于网络编程的类,了解URL.Socket.InetAdd ...

  6. Android Bander设计与实现 - 设计

    Binder Android IPC Linux 内核 驱动 摘要 Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥有管道,system V IPC,socket等IPC ...

  7. Django中的QuerySet

    一.QuerySet 查询集,类似一个列表,包含了满足查询条件的所有项.QuerySet 可以被构造,过滤,切片,做为参数传递,这些行为都不会对数据库进行操作.只有你查询的时候才真正的操作数据库.意味 ...

  8. python随笔(二)

    range(2,10):不包括10 range(2,10,3):步长为3 range(10,2,-1):从10到2,步长-1.

  9. TImage 显示 资源中 的图片、TResourceStream、资源文件

    unit Unit5; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...

  10. manacher模板

    转自:http://blog.csdn.net/zzkksunboy/article/details/72600679 作用 线性时间解决最长回文子串问题. 思想 Manacher充分利用了回文的性质 ...