【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 ...
随机推荐
- C++11 之 scoped enum
C++11 枚举类型是“域化的” (scoped enum),相比 C++98 枚举类型的“非域化” (unscoped enum),具有如下优点: 1 命名空间污染 一般来说,声明在花括号内 ...
- Stanford机器学习笔记-3.Bayesian statistics and Regularization
3. Bayesian statistics and Regularization Content 3. Bayesian statistics and Regularization. 3.1 Und ...
- html5的小知识点小集合
html5的小知识点小集合 html5知识 1. Doctype作用?标准模式与兼容模式各有什么区别? (1).<!DOCTYPE>声明位于位于HTML文档中的第一行,处于< ...
- JMeter学习(十七)JMeter测试Java
目的:对Java程序进行测试 目录 一.核心步骤 二.实例 三.JMeter Java Sampler介绍 四.自带Java Request Sampler 一.核心步骤 1.创建一个Java工程: ...
- guava常用操作
Jack47 我思故我在 Google Java编程库Guava介绍 本系列想介绍下Java下开源的优秀编程库--Guava[ˈgwɑːvə].它包含了Google在Java项目中使用一些核心库,包含 ...
- webapp开发需要注意的浏览器内核知识
Web App:1.开发成本较低使用web开发技术就可以轻松的完成web app的开发2.升级较简单升级不需要通知用户,在服务端更新文件即可,用户完全没有感觉3.维护比较轻松和一般的web一样,维护比 ...
- 在表单中元素的onchange事件的兼容性问题
onchange:在值发生改变的时候触发 text:当光标离开的时候如果内容有变化就触发 radio/check:标准浏览器下点击的时候只要值变了就触发 非标准浏览器下焦点离开的时候如果值变了就触发
- .NET Framework 中的所有类型
.NET Framework 中的所有类型不是值类型就是引用类型. 值类型是使用对象实际值来表示对象的数据类型. 如果向一个变量分配值类型的实例,则该变量将被赋以该值的全新副本. 引用类型是使用对对象 ...
- Java 集合系列16之 HashSet详细介绍(源码解析)和使用示例
概要 这一章,我们对HashSet进行学习.我们先对HashSet有个整体认识,然后再学习它的源码,最后再通过实例来学会使用HashSet.内容包括:第1部分 HashSet介绍第2部分 HashSe ...
- SQL GETDATE()日期格式化函数
Sql Server 中一个非常强大的日期格式化函数 Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AMSelect CONV ...