一开始看到$\frac{\sum_{}}{\sum_{}}$就想到了01分数规划但最终还是看了题解

二分完后的点分治,只需要维护一个由之前处理过的子树得出的$tb数组$,然后根据遍历每个当前的子树上的结点的深度来确定$tb数组$中的滑块。

因为分数规划要找的是$max$,BFS遍历当前结点的深度越来越大,这样滑块也是单调向右滑动,所以滑块里的最大值就应当用单调队列解决

#include<cstdio>
#include<algorithm>
#define read(x) x=getint()
#define N 100003
#define eps 0.0001
#define max(a,b) (a)>(b)?a:b
using namespace std;
inline int getint() {
char c; int fh = 1, k = 0;
for( ; c < '0' || c > '9'; c = getchar()) if ( c == '-') fh = -1;
for( ; c >= '0' && c <= '9'; c = getchar()) k = k * 10 + c - '0';
return k * fh;
}
struct node {
int nxt, to, w;
} E[N << 1];
bool vis[N];
double ans = 0.0, limi = 0.0, dis[N], tb[N];
int sz[N], n, cnt = 0, L, U, point[N], root, rtm = N, fa[N], q[N], dq[N], deep[N];
inline void ins( int x, int y, int z) {++cnt; E[cnt].nxt = point[x]; E[cnt].to = y; E[cnt].w = z; point[x] = cnt;}
inline void fdrt( int x, int fa, int s) {
sz[x] = 1;
int ma = 0;
for( int tmp = point[x]; tmp; tmp = E[tmp].nxt)
if ( !vis[E[tmp].to] && E[tmp].to != fa) {
fdrt( E[tmp].to, x, s);
sz[x] += sz[E[tmp].to];
ma = max( ma, sz[E[tmp].to]);
}
ma = max( ma, s - ma);
if ( ma < rtm) {
rtm = ma;
root = x;
}
}
inline bool can( int x, double M) {
int le = 0, head, tail, h, t, now;
for( int tmp = point[x]; tmp; tmp = E[tmp].nxt)
if ( !vis[E[tmp].to]) {
head = 0;
tail = 1;
q[0] = E[tmp].to;
fa[E[tmp].to] = x;
deep[E[tmp].to] = 1;
dis[E[tmp].to] = (double) E[tmp].w - M;
while ( head != tail) {
now = q[head];
++head; if ( head >= N) head %= N;
for( int i = point[now]; i; i = E[i].nxt)
if ( !vis[E[i].to] && E[i].to != fa[now]) {
q[tail] = E[i].to;
fa[E[i].to] = now;
deep[E[i].to] = deep[now] + 1;
dis[E[i].to] = dis[now] + (double) E[i].w - M;
++tail; if ( tail >= N) tail %= N;
}
}
h = 1;
t = 0;
now = le;
for( int i = 0; i < tail; ++i) {
while ( deep[q[i]] + now >= L && now >= 0) {
while ( h <= t && tb[dq[t]] < tb[now])
--t;
dq[++t] = now;
--now;
}
while ( h <= t && deep[q[i]] + dq[h] > U)
++h;
if ( h <= t && dis[q[i]] + tb[dq[h]] >= 0)
return 1;
}
for( int i = le + 1; i <= deep[q[tail-1]]; ++i)
tb[i] = -1E9;
for( int i = 0; i < tail; ++i)
tb[deep[q[i]]] = max( tb[deep[q[i]]], dis[q[i]]);
le = max( le, deep[q[tail-1]]);
}
return 0;
}
inline void work( int x) {
double left = ans, right = limi, mid;
while ( right - left > eps) {
mid = ( left + right) / 2;
if ( can ( x, mid))
left = mid;
else
right = mid;
}
ans = left;
}
inline void dfs( int x, int s) {
vis[x] = 1;
work( x);
for( int tmp = point[x]; tmp; tmp = E[tmp].nxt)
if ( !vis[E[tmp].to]) {
rtm = N;
int ss = sz[E[tmp].to] < sz[x] ? sz[E[tmp].to] : s - sz[x];
fdrt( E[tmp].to, -1, ss);
if ( sz[E[tmp].to] > L)
dfs( root, ss);
}
}
int main() {
read(n); read(L); read(U);
int a, b, c;
for( int i = 1; i < n; ++i) {
read(a); read(b); read(c);
ins( a, b, c);
ins( b, a, c);
limi = max( limi, c);
}
fdrt( 1, -1, n);
dfs( 1, n);
printf( "%.3lf\n", ans);
return 0;
}

这样就可以了

【BZOJ 1758】【WC 2010】重建计划 分数规划+点分治+单调队列的更多相关文章

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

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

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

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

  3. [WC2010]重建计划(分数规划+点分治+单调队列)

    题目大意:给定一棵树,求一条长度在L到R的一条路径,使得边权的平均值最大. 题解 树上路径最优化问题,不难想到点分治. 如果没有长度限制,我们可以套上01分数规划的模型,让所有边权减去mid,求一条路 ...

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

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

  5. BZOJ 1758: [Wc2010]重建计划 01分数规划+点分治+单调队列

    code: #include <bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in", ...

  6. BZOJ 1758 / Luogu P4292 [WC2010]重建计划 (分数规划(二分/迭代) + 长链剖分/点分治)

    题意 自己看. 分析 求这个平均值的最大值就是分数规划,二分一下就变成了求一条长度在[L,R]内路径的权值和最大.有淀粉质的做法但是我没写,感觉常数会很大.这道题可以用长链剖分做. 先对树长链剖分. ...

  7. [WC 2010]重建计划

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

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

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

  9. [WC2010][BZOJ1758]重建计划-[二分+分数规划+点分治]

    Description 传送门 Solution 看到那个式子,显然想到分数规划...(不然好难呢) 然后二分答案,则每条边的权值设为g(e)-ans.最后要让路径长度在[L,U]范围内的路径权值&g ...

随机推荐

  1. 怎么解决ZBrush保存历史记录太多问题

    经常有用户反映说ZBrush ®保存历史记录太多了,导致文件太大了!模型已经是降低级别保存了,在保存历史记录的时候还是很慢很慢,不知道怎么才能减少ZBrush保存的历史步骤的多少.针对这一问题,小编统 ...

  2. jmeter的压力测试

    Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试. 以下为压力测试的简单介绍 1.在测试计划下增加一个线程组 2.线程组的内容需要进行编辑,根据压力测 ...

  3. 嵌入式Linux驱动学习之路(五)u-boot启动流程分析

    这里说的u-boot启动流程,值得是从上电开机执行u-boot,到u-boot,到u-boot加载操作系统的过程.这一过程可以分为两个过程,各个阶段的功能如下. 第一阶段的功能: 硬件设备初始化. 加 ...

  4. [No00005C]我也入住Markdown

    概览 宗旨 Markdown 的目标是实现「易读易写」. 可读性,无论如何,都是最重要的.一份使用 Markdown 格式撰写的文件应该可以直接以纯文本发布,并且看起来不会像是由许多标签或是格式指令所 ...

  5. 本地 Maven项目部署到Nexus Repository

    配置Nexus Repository 打开WEB管理界面:http://localhost:8081/nexus/index.html 点击右上角Log In进行登录,默认帐号:admin.密码:ad ...

  6. PL/SQL异常处理方法

    PL/SQL异常处理方法   1:什么是异常处理: PL/SQL提供一个功能去处理异常,在PL/SQL块中叫做异常处理,使用异常处理我们能够测试代码和避免异常退出. PL/SQL异常信息包含三个部分: ...

  7. python处理经过gzip压缩的网页内容

    Python在进行网页抓取时,有时会获取到经过gzip压缩后的数据(体积小,传输快),导致无法阅读和使用. 如图所示,为http原始报文.可以看到,header区域的“Content-Encoding ...

  8. Linux shell的输入输出

    echo --echo命令可以显示文本行或变量,或者把字符串输入到文件 --echo [option] string -e 解析转义字符 例如:echo -e "nimenhao\nasfd ...

  9. 洛谷 1016 / codevs 1046 旅行家的预算

    https://www.luogu.org/problem/show?pid=1016 http://codevs.cn/problem/1046/ 题目描述 Description 一个旅行家想驾驶 ...

  10. ehcache2.8.3入门示例:hello world

    一.pom.xml 依赖项 <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehc ...