一开始看到$\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. U3D的飞船太空射击例子中,使用coroutine

    coroutine 协同程序与线程差不多,也就是一条执行序列,拥有自己独立的栈,局部变量和指令指针,同时又与其它协同程序共享全局变量和其它大部分东西.线程与协同程序的主要区别在于,一个具有多线程的程序 ...

  2. PLSQL Developer win7 64位 安装方法

    安装32位的Oracle客户端( instantclient-basic-win32-11.2.0.1.0).Win7 64位系统暂无PLSQLDeveloper,所以下一个32位的. 下载insta ...

  3. java 26 - 6 网络编程之 TCP协议 传输思路 以及 代码

    TCP传输 Socket和ServerSocket 建立客户端和服务器 建立连接后,通过Socket中的IO流进行数据的传输 关闭socket 同样,客户端与服务器是两个独立的应用程序 TCP协议发送 ...

  4. splay总结

    以此文纪念人生首次竞赛大选 这里主要讲一讲splay的区间操作,我讲的是指针实现,程序的效率可能比较低,更偏重代码的可读可写性,语言风格不是很优美有效,不喜勿喷 零.初始化结构体 1)这里主要是初始化 ...

  5. javascript中String的fromCharCode()方法

    前几天遇到一个bug,后端的模板引擎在输出形如: <div title="111 aaa">内容</div> 这样的内容时,无法输出' '空格,所以只能用' ...

  6. Javascript备忘复习笔记1

    一.字符串操作 1.大小写 var s = "hello"; undefined g = s.toUpperCase(); "HELLO" g; "H ...

  7. PAT 1026. 程序运行时间(15)

    要获得一个C语言程序的运行时间,常用的方法是调用头文件time.h,其中提供了clock()函数,可以捕捉从程序开始运行到clock()被调用时所耗费的时间.这个时间单位是clock tick,即&q ...

  8. BZOJ 1854 【Scoi2010】 游戏

    Description lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的某一个属性 ...

  9. HTML5添加 video 视频标签后仍然无法播放的解决方法 IIS添加MIEI类型

    现象:插入如下代码后仍然无法看视频(注:视频已确认为浏览器支持格式) <video controls="controls" width="500px" h ...

  10. C#字符串默认值

    using System; class MYTestX { class CT { } class CO { public CT ott; //默认是null public string strx;// ...