【BZOJ 1758】【WC 2010】重建计划 分数规划+点分治+单调队列
一开始看到$\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】重建计划 分数规划+点分治+单调队列的更多相关文章
- BZOJ.1758.[WC2010]重建计划(分数规划 点分治 单调队列/长链剖分 线段树)
题目链接 BZOJ 洛谷 点分治 单调队列: 二分答案,然后判断是否存在一条长度在\([L,R]\)的路径满足权值和非负.可以点分治. 对于(距当前根节点)深度为\(d\)的一条路径,可以用其它子树深 ...
- bzoj 1758 [Wc2010]重建计划 分数规划+树分治单调队列check
[Wc2010]重建计划 Time Limit: 40 Sec Memory Limit: 162 MBSubmit: 4345 Solved: 1054[Submit][Status][Disc ...
- [WC2010]重建计划(分数规划+点分治+单调队列)
题目大意:给定一棵树,求一条长度在L到R的一条路径,使得边权的平均值最大. 题解 树上路径最优化问题,不难想到点分治. 如果没有长度限制,我们可以套上01分数规划的模型,让所有边权减去mid,求一条路 ...
- BZOJ1758: [Wc2010]重建计划(01分数规划+点分治+单调队列)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1758 01分数规划,所以我们对每个重心进行二分.于是问题转化为Σw[e]-mid>=0, ...
- BZOJ 1758: [Wc2010]重建计划 01分数规划+点分治+单调队列
code: #include <bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in", ...
- BZOJ 1758 / Luogu P4292 [WC2010]重建计划 (分数规划(二分/迭代) + 长链剖分/点分治)
题意 自己看. 分析 求这个平均值的最大值就是分数规划,二分一下就变成了求一条长度在[L,R]内路径的权值和最大.有淀粉质的做法但是我没写,感觉常数会很大.这道题可以用长链剖分做. 先对树长链剖分. ...
- [WC 2010]重建计划
Description Input 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案, ...
- BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP
题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...
- [WC2010][BZOJ1758]重建计划-[二分+分数规划+点分治]
Description 传送门 Solution 看到那个式子,显然想到分数规划...(不然好难呢) 然后二分答案,则每条边的权值设为g(e)-ans.最后要让路径长度在[L,U]范围内的路径权值&g ...
随机推荐
- Appium学习实践(一)简易运行Appium
环境: Appium 1.4.13 OS X 10.10.5 真机已安装app,或者未安装,通过ipa文件来安装,并启动Appium Inspector 点击Appium中的放大镜后,自动运行App ...
- 第10章 同步设备I/O和异步设备I/O(1)_常见设备及CreateFile函数
10.1 打开和关闭设备 10.1.1 设备的定义——在Windows中可以与之进行通信的任何东西. (1)常见设备及用途 设备 用途 用来打开设备的函数 文件 永久存储任何数据 CreateFile ...
- 有关数据库行、锁 的几个问题(rowlock)
行锁的基本说明: SELECT au_lname FROM authors WITH (NOLOCK) 锁定提示 描述 HOLDLOC ...
- 使用eclipse进行Android编程发生崩溃的一个问题及解决办法
刚才在使用eclipse的时候发生了vm占用过高而无法使用的问题,最初我以为只要重启eclipse就可以解决,重启之后仍然没有效果.重启PC之后打开eclipse仍然无法打开.eclipse是有自己的 ...
- cocos 锚点、包围盒
cocos中,setPosition就是设置一个sprite的锚点在父级元素的坐标 默认锚点是sprite矩形的中点 可以用getBoundingBox返回一个sprite所占矩形范围.范围用Rect ...
- jquery工具方法proxy
proxy : 改变this指向 使用方法1:function show(){ alert(this); }$.proxy(show,document)(); //document 使用方法2:fu ...
- IE8以下不支持getElementsByClassName方法
function getElementsByClassName(classStr,tagName,element){ tagName = (tagName || '*'); element = (el ...
- Netty Client重连实现
from:http://itindex.net/detail/54161-netty-client 当我们用Netty实现一个TCP client时,我们当然希望当连接断掉的时候Netty能够自动重连 ...
- 使用ViewBag传送数据从控制器至视图
前一篇<ASP.NET MVC读取XML并使用ViewData显示>http://www.cnblogs.com/insus/p/4308740.html 中,在控制器中使用了ViewDa ...
- 设置apache https服务
配置http.conf,所在位置d:\wamp\bin\apache\apache2.4.9\conf\http.conf LoadModule socache_shmcb_module modu ...