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

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

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

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

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

  1. #include<cstdio>
  2. #include<vector>
  3. #include<algorithm>
  4. #define rep(i,l,r) for (int i=(l); i<=(r); i++)
  5. #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
  6. using namespace std;
  7.  
  8. const int N=;
  9. const double eps=1e-,inf=1e9;
  10. bool vis[N];
  11. int n,L,R,u,v,w,S,rt,tot,sz[N],f[N],he[N],d[N],q[N];
  12. int cnt,h[N],pre[N],to[N<<],val[N<<],nxt[N<<];
  13. double ans,dis[N],s1[N],s2[N];
  14. vector<int>ve;
  15. void add(int u,int v,int w){ to[++cnt]=v; val[cnt]=w; nxt[cnt]=h[u]; h[u]=cnt; }
  16.  
  17. bool cmp(int a,int b){ return he[a]<he[b]; }
  18.  
  19. void get(int x,int fa){
  20. sz[x]=; f[x]=;
  21. For(i,x) if ((k=to[i])!=fa && !vis[k])
  22. get(k,x),f[x]=max(f[x],sz[k]),sz[x]+=sz[k];
  23. f[x]=max(f[x],S-sz[x]);
  24. if (f[x]<f[rt]) rt=x;
  25. }
  26.  
  27. void dfs(int x,int fa){
  28. d[x]=d[fa]+; he[x]=;
  29. For(i,x) if ((k=to[i])!=fa && !vis[k])
  30. pre[k]=val[i],dfs(k,x),he[x]=max(he[x],he[k]+);
  31. }
  32.  
  33. void dfs2(int x,int fa,double mid){
  34. dis[x]=dis[fa]+pre[x]-mid; s2[d[x]]=max(s2[d[x]],dis[x]);
  35. For(i,x) if ((k=to[i])!=fa && !vis[k]) dfs2(k,x,mid);
  36. }
  37.  
  38. bool jud(double mid){
  39. double res=-inf;
  40. rep(i,,tot){
  41. int k=ve[i],st=,ed=; dis[rt]=;
  42. rep(j,,he[k]) s2[j]=-inf; dfs2(k,rt,mid);
  43. rep(j,,he[k]){
  44. if (st<=ed && q[st]>R-j) st++;
  45. if (L-j<=he[k]){
  46. while (st<=ed && s1[q[ed]]<s1[L-j]) ed--;
  47. q[++ed]=L-j;
  48. }
  49. if (st<=ed) res=max(res,s1[q[st]]+s2[j]);
  50. }
  51. rep(j,,he[k]) s1[j]=max(s1[j],s2[j]);
  52. }
  53. return res>;
  54. }
  55.  
  56. void solve(int x){
  57. vis[x]=; d[]=-; dfs(x,); dis[x]=; ve.clear();
  58. For(i,x) if (!vis[k=to[i]]) ve.push_back(k=to[i]);
  59. tot=ve.size()-;
  60. if (tot==-) return;
  61. sort(ve.begin(),ve.end(),cmp);
  62. int ed=he[ve[tot]];
  63. double L=ans,R=1e6;
  64. while (L+eps<R){
  65. double mid=(L+R)/;
  66. rep(i,,ed) s1[i]=-inf; s1[]=;
  67. if (jud(mid)) L=mid; else R=mid;
  68. }
  69. ans=max(ans,L);
  70. For(i,x) if (!vis[k=to[i]]) rt=,S=sz[k],get(k,x),solve(rt);
  71. }
  72.  
  73. int main(){
  74. freopen("bzoj1758.in","r",stdin);
  75. freopen("bzoj1758.out","w",stdout);
  76. scanf("%d%d%d",&n,&L,&R);
  77. rep(i,,n) scanf("%d%d%d",&u,&v,&w),add(u,v,w),add(v,u,w);
  78. f[]=n+; S=n; rt=; get(,);
  79. solve(rt); printf("%.3lf\n",ans);
  80. return ;
  81. }

[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. jQuery入门——(二)

    0.基本知识 $与jQuery等价,$.fun代表jQuery的全局方法. jQuery必须首先导入JQuery库, jQuery的事件都不带on,例如 $("#btn").cli ...

  2. 那些代表性的HTTP状态码,你还只知道404吗?快来看看吧【转】

    前言 在网络上发送请求后,经常会根据请求的状态码去判断请求的成功失败与否,常见的状态码有200,404,500. 不过你以为HTTP请求的状态码就只有这么几个么?其实是远远比这个多的. 今天这篇文章我 ...

  3. python 根据输入的内容输出类型

    类型判断 from functools import singledispatch import numbers from collections import abc from collection ...

  4. 读书笔记 effective c++ Item 52 如果你实现了placement new,你也要实现placement delete

    1. 调用普通版本的operator new抛出异常会发生什么? Placement new和placement delete不是C++动物园中最常遇到的猛兽,所以你不用担心你对它们不熟悉.当你像下面 ...

  5. linux编译警告 will be initialized after

    http://blog.chinaunix.net/uid-17019762-id-3152012.html 作为一个有强迫症的人,实在是受不了 warning 的存在 这个warning是由于初始化 ...

  6. webpack轻松入门教程

    webpack之傻瓜式教程及前端自动化入门 接触webpack也有挺长一段时间了,公司的项目也是一直用着webpack在打包处理,但前几天在教新人的情况下,遇到了一个问题,那就是:尽管网上的webpa ...

  7. [新手]在macOS环境下安装xdebug

    使用环境 masOS 10.12 使用MAMP安装的PHP环境   在新安装的系统中,安装xdebug,遇到了一些小问题;   P.S. 重新按照xdebug官网的指南安装了一次,把上次安装失败的xd ...

  8. c语言快速排序算法(转)

    原文链接http://blog.csdn.net/morewindows/article/details/6684558 快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常 ...

  9. CCF CSP 201509-3 模板生成系统

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201509-3 模板生成系统 问题描述 成成最近在搭建一个网站,其中一些页面的部分内容来自数据 ...

  10. Android Activity、Service、BroadcastReceiver 的生命周期

    Activity.Service.BroadcastReceiver这三个组建是Android开发中最常使用到的组件,在它们的生命周期的各个阶段我们需要针对性的做些事情,了解这些组件的生命周期有利于我 ...