[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\)的一条路径,可以用其它子树深 ...
随机推荐
- qt中int与string的相互转换
我经常搞错这个问题,一直以为整形int b可以直接使用函数toString呢! 但是在qtCreator中在整形后面不管怎么按点(可以自动提示)他就是不给我提示,我就纳闷了这样居然不行 百度了之后才知 ...
- 【CTF MISC】pyc文件反编译到Python源码-2017世安杯CTF writeup详解
1.题目 Create-By-SimpleLab 适合作为桌面的图片 首先是一张图片,然后用StegSolve进行分析,发现二维码 扫码得到一串字符 03F30D0A79CB0558630000000 ...
- ansible批量修改linux服务器密码的playbook
从网上找到批量修改Linux服务器root密码的playbook. 使用方法: 1.输入要修改的inventory组 2.按需要,在playbook中输入要修改的IP.新密码,如下: - hosts: ...
- OpenStack Benchmark - Rally
作为以基于OpenStack的云平台的基准测试工具 -- Rally, 其功能不仅是测试云的性能&&稳定性, 还可以安装OpenStack,以及以良好的表现形式(web 页面)展现测试 ...
- Python的日志记录-logging模块的使用
一.日志 1.1什么是日志 日志是跟踪软件运行时所发生的事件的一种方法,软件开发者在代码中调用日志函数,表明发生了特定的事件,事件由描述性消息描述,同时还包含事件的重要性,重要性也称为级别或严重性. ...
- python之assert断言
assert只是一个检查,为真不做任何事,不为真时,抛出异常,并包含错误信息 1.根据布尔值判断 2.判断是否相等 3.返回值是否为空 4.是否包含某值 x in y 其他方法,可以参考http:// ...
- python_接口自动化测试框架
本文总结分享介绍接口测试框架开发,环境使用python3+selenium3+unittest+ddt+requests测试框架及ddt数据驱动,采用Excel管理测试用例等集成测试数据功能,以及使用 ...
- Centos7.3安装和配置jre1.8
在正式环境里 我们可以不安装jdk ,仅仅安装Java运行环境 jre即可: 第一步:下载jre 我们去oracle官方下载下jre http://www.oracle.com/technetwork ...
- Es官方文档整理-3.Doc Values和FieldData
Es官方文档整理-3.Doc Values和FieldData 1.Doc Values 聚合使用一个叫Doc Values的数据结构.Doc Values使聚合更快.更高效且内存友好. Doc Va ...
- 利用sql server直接创建日历
看到网上有高手直接用sql查询创建日历,也想自己动手实践一遍.笔者这里的实现和网上的都没有什么区别,思路也没有什么新意.觉得好玩,就把它记下来吧. 一.准备知识1.sql的with关键字关于with和 ...