[BZOJ1758][WC2010]重建计划(点分治+单调队列)
点分治,对于每个分治中心,考虑求出经过它的符合长度条件的链的最大权值和。
从分治中心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]重建计划(点分治+单调队列)的更多相关文章
- P4292 [WC2010]重建计划 点分治+单调队列
题目描述 题目传送门 分析 看到比值的形式就想到 \(01分数规划\),二分答案 设当前的值为 \(mids\) 如果存在\(\frac{\sum _{e \in S} v(e)}{|S|} \geq ...
- BZOJ1758: [Wc2010]重建计划
题解: 这题我居然做了一星期?... 平均值的极值其实也可以算是一种分数规划,只不过分母上b[i]=1 然后我们就可以二分这个值.类似与 HNOI最小圈 如果没有 链的长度的限制的话,我们直接两遍df ...
- BZOJ1758 WC2010 重建计划 二分答案、点分治、单调队列
传送门 看到平均数最大,自然地想到二分答案.那么我们的$check$函数就是要求:是否存在一条长度在$[L,U]$的路径,满足其权值和$\geq 0$. 看到长度在$[L,U]$,自然地想到点分治求解 ...
- BZOJ1758: [Wc2010]重建计划(01分数规划+点分治+单调队列)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1758 01分数规划,所以我们对每个重心进行二分.于是问题转化为Σw[e]-mid>=0, ...
- bzoj1758 [Wc2010]重建计划 & bzoj2599 [IOI2011]Race
两题都是树分治. 1758这题可以二分答案avgvalue,因为avgvalue=Σv(e)/s,因此二分后只需要判断Σv(e)-s*avgvalue是否大于等于0,若大于等于0则调整二分下界,否则调 ...
- BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP
题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...
- 2019.01.21 bzoj1758: [Wc2010]重建计划(01分数规划+长链剖分+线段树)
传送门 长链剖分好题. 题意简述:给一棵树,问边数在[L,R][L,R][L,R]之间的路径权值和与边数之比的最大值. 思路: 用脚指头想都知道要01分数规划. 考虑怎么checkcheckcheck ...
- bzoj 1758 [Wc2010]重建计划 分数规划+树分治单调队列check
[Wc2010]重建计划 Time Limit: 40 Sec Memory Limit: 162 MBSubmit: 4345 Solved: 1054[Submit][Status][Disc ...
- BZOJ.1758.[WC2010]重建计划(分数规划 点分治 单调队列/长链剖分 线段树)
题目链接 BZOJ 洛谷 点分治 单调队列: 二分答案,然后判断是否存在一条长度在\([L,R]\)的路径满足权值和非负.可以点分治. 对于(距当前根节点)深度为\(d\)的一条路径,可以用其它子树深 ...
随机推荐
- jQuery入门——(二)
0.基本知识 $与jQuery等价,$.fun代表jQuery的全局方法. jQuery必须首先导入JQuery库, jQuery的事件都不带on,例如 $("#btn").cli ...
- 那些代表性的HTTP状态码,你还只知道404吗?快来看看吧【转】
前言 在网络上发送请求后,经常会根据请求的状态码去判断请求的成功失败与否,常见的状态码有200,404,500. 不过你以为HTTP请求的状态码就只有这么几个么?其实是远远比这个多的. 今天这篇文章我 ...
- python 根据输入的内容输出类型
类型判断 from functools import singledispatch import numbers from collections import abc from collection ...
- 读书笔记 effective c++ Item 52 如果你实现了placement new,你也要实现placement delete
1. 调用普通版本的operator new抛出异常会发生什么? Placement new和placement delete不是C++动物园中最常遇到的猛兽,所以你不用担心你对它们不熟悉.当你像下面 ...
- linux编译警告 will be initialized after
http://blog.chinaunix.net/uid-17019762-id-3152012.html 作为一个有强迫症的人,实在是受不了 warning 的存在 这个warning是由于初始化 ...
- webpack轻松入门教程
webpack之傻瓜式教程及前端自动化入门 接触webpack也有挺长一段时间了,公司的项目也是一直用着webpack在打包处理,但前几天在教新人的情况下,遇到了一个问题,那就是:尽管网上的webpa ...
- [新手]在macOS环境下安装xdebug
使用环境 masOS 10.12 使用MAMP安装的PHP环境 在新安装的系统中,安装xdebug,遇到了一些小问题; P.S. 重新按照xdebug官网的指南安装了一次,把上次安装失败的xd ...
- c语言快速排序算法(转)
原文链接http://blog.csdn.net/morewindows/article/details/6684558 快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高,因此经常 ...
- CCF CSP 201509-3 模板生成系统
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201509-3 模板生成系统 问题描述 成成最近在搭建一个网站,其中一些页面的部分内容来自数据 ...
- Android Activity、Service、BroadcastReceiver 的生命周期
Activity.Service.BroadcastReceiver这三个组建是Android开发中最常使用到的组件,在它们的生命周期的各个阶段我们需要针对性的做些事情,了解这些组件的生命周期有利于我 ...