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

从分治中心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. HTML5之2D物理引擎 Box2D for javascript Games 系列 第二部分

    这是系列第二部分,之前部分在本博客中找 源码demo存放在https://github.com/willian12345/Box2D-for-Javascript-Games 向世界添加刚体 刚体(B ...

  2. mvn打war包以及解压包的方法

    有时候我们需要查看打成war包之后的目录,如果是maven项目我们可以直接用maven打包. 1.maven打包: 第一种: mvn package 如果不行先 mvn clean一下 第二种:(掌握 ...

  3. 【NOI题解】【bzoj题解】NOI2008 bzoj1063 道路设计

    @ACMLCZH学长出的毒瘤题T3.再也不是“善良”的出题人了. 题意:bzoj. 题解: 经典的树形DP题目,屡见不鲜了,然而我还是没有写出来. 这一类的题目有很多,例如这里的C题. 主要套路是把对 ...

  4. 搭建本地git服务器

    最近因为项目需求,需要实现一个原型系统,加上后期项目需要多人协作,考虑采用了git做版本控制. 这里主要简要描述下git服务器和客户端的搭建和配置. 1.git服务器 (1)安装git sudo ap ...

  5. CentOS7 修改网卡名称

    vi /etc/sysconfig/grub 增加net.ifnames=0 biosdevname=0 执行:grub2-mkconfig -o /boot/grub2/grub.cfg

  6. 32 Profiling Go Programs 分析go语言项目

    Profiling Go Programs  分析go语言项目 24 June 2011 At Scala Days 2011, Robert Hundt presented a paper titl ...

  7. No.20 selenium学习之路之文件读写

    1.open 使用open打开文件后一定要记得调用文件对象的close()方法.比如可以用try/finally语句来确保最后能关闭文件. file_object = open('thefile.tx ...

  8. 洛谷P3811乘法逆元

    传送门 线性递推 #include <iostream> #include <cstdio> #include <cstring> #include <alg ...

  9. 一张图来帮你理解 SOA

    SOA 曾经一度是技术领域中最难以理解的一个概念.SOA 似乎让很多人感到困惑 - 一般来讲这是由于人们认为它拥有几乎神奇的力量.事实上 SOA 只是一个很简单的概念:SOA 由诸如 C++ 和 Ja ...

  10. ROS二进制日志包 ROS binary logger package

    原文网址: 1 http://www.ros.org/news/2017/02/ros-binary-logger-package.html 2 https://github.com/CNR-ITIA ...