[Wc2010]重建计划

Time Limit: 40 Sec  Memory Limit: 162 MB
Submit: 4345  Solved: 1054
[Submit][Status][Discuss]

Description

Input

第一行包含一个正整数N,表示X国的城市个数.
第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限

接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai,Bi,Vi分别表示道路(Ai,Bi),其价值为Vi 其中城市由1..N进行标号

Output

输出最大平均估值,保留三位小数

Sample Input

4
2 3
1 2 1
1 3 2
1 4 3

Sample Output

2.500

HINT

N<=100000,1<=L<=U<=N-1,Vi<=1000000 新加数据一组 By leoly,但未重测..2016.9.27

题解:点分上是一个log,二分是一个log,然后是单调队列判断,n,总复杂度O(nlogn^2)

hzwer的代码十分不优秀,应该是按照最低深度从小到大去个棵子树去判断才可以,不然是不行的,

不然会是复杂度退化成n^2

改了比较siz还是T,不知道为什么了。

 #include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<vector> #define inf 1000000007
#define eps 0.0001
#define N 100007
#define M 200007
#define ll long long
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} int n,S,L,U,rt,lim;
double ans;
int cnt,hed[N],rea[M],val[M],nxt[M];
int sz[N],fa[N],f[N],dep[N];
int q[N],dq[N];
bool flag[N];
double dis[N],mx[N];
int num[N*],xz,shu[N*]; void add(int u,int v,int w)
{
nxt[++cnt]=hed[u];
hed[u]=cnt;
rea[cnt]=v;
val[cnt]=w;
}
void get_root(int u,int fa)
{
sz[u]=,f[u]=;
for (int i=hed[u];i!=-;i=nxt[i])
{
int v=rea[i];
if (v==fa||flag[v]) continue;
get_root(v,u);
sz[u]+=sz[v];
f[u]=max(f[u],sz[v]);
}
f[u]=max(f[u],S-sz[u]);
if (f[u]<=f[rt])rt=u;
}
bool check(int rt,double zhi)
{
int up=;
for (int i=hed[rt];i!=-;i=nxt[i])
{
int v=rea[i];double fee=(double)val[i]-zhi;
if (flag[v])continue;
int hd=,tl=;
q[]=v;
fa[v]=rt,dep[v]=;
dis[v]=fee;
while(hd!=tl)
{
int now=q[hd];hd++;
for (int i=hed[now];i!=-;i=nxt[i])
{
int v=rea[i];double fee=(double)val[i]-zhi;
if (v==fa[now]||flag[v])continue;
q[tl++]=v;
fa[v]=now,dep[v]=dep[now]+;
dis[v]=dis[now]+fee;
}
}
int l=,r=,now=up;
for (int i=;i<tl;i++)
{
int x=q[i];
while(dep[x]+now>=L&&now>=)
{
while(l<=r&&mx[dq[r]]<mx[now])r--;
dq[++r]=now;
now--;
}
while(l<=r&&dep[x]+dq[l]>U)l++;
if (l<=r&&dis[x]+mx[dq[l]]>=)return ;
}
for (int i=up+;i<=dep[q[tl-]];i++)mx[i]=-inf;
for (int i=;i<tl;i++)
{
int x=q[i];
mx[dep[x]]=max(mx[dep[x]],dis[x]);
}
up=max(up,dep[q[tl-]]);
}
return ;
}
void cal(int u)//可以
{
double l=ans,r=lim,mid;
while(r-l>eps)
{
mid=(l+r)/;
if(check(u,mid))l=mid;
else r=mid;
}
ans=l;
}
bool cmp(int x,int y)
{
return shu[x]<shu[y];
}
void solve(int u)
{
cal(u);
flag[u]=;int yl=xz,Sum=S;
for (int i=hed[u];i!=-;i=nxt[i])
{
int v=rea[i];
if (flag[v])continue;
rt=;
if (sz[v]<sz[u])S=sz[v];
else S=Sum-sz[u];
get_root(v,);
if(sz[v]>L)num[++xz]=rt,shu[++xz]=S;
}
sort(num+yl+,num+xz+,cmp);
for (int i=yl+;i<=xz;i++)
solve(num[i]);
xz=yl;
}
int main()
{
memset(hed,-,sizeof(hed));
n=read(),L=read(),U=read();
for (int i=;i<n;i++)
{
int u=read(),v=read(),w=read();
add(u,v,w),add(v,u,w);
lim=max(lim,w);
}
f[]=n;
rt=,S=n;
get_root(,);
solve(rt);
printf("%.3lf",ans);
}

bzoj 1758 [Wc2010]重建计划 分数规划+树分治单调队列check的更多相关文章

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

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

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

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

  3. 【BZOJ 1758】【WC 2010】重建计划 分数规划+点分治+单调队列

    一开始看到$\frac{\sum_{}}{\sum_{}}$就想到了01分数规划但最终还是看了题解 二分完后的点分治,只需要维护一个由之前处理过的子树得出的$tb数组$,然后根据遍历每个当前的子树上的 ...

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

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

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

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

  6. bzoj 1758: [Wc2010]重建计划

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

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

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

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

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

  9. BZOJ 1758: [Wc2010]重建计划 [暂时放弃]

    今天晚上思维比较乱,以后再写写吧#include <iostream> #include <cstdio> #include <cstring> #include ...

随机推荐

  1. oracle 数据导到 sql server

    方法一: navicate:用法比较简单,选择工具-数据传输就可以了.目前测试了下暂时没遇到什么问题. 方法二: Microsoft SQL Server Migration Assistant 8. ...

  2. 实验1 c语言最基本内容

    part 1 验证性内容 总结:经受了数组和结构体的双重折磨后,发现这部分好简单...现在没啥问题了... part  2  补全程序 1.判断奇偶 // 程序功能: // 要求用户从键盘输入一个整数 ...

  3. FZOJβ #31.字符串

    http://1572m36l09.iask.in:30808/problem/31 首先转化为保留尽量少的段使得字典序最大.考虑逐字符确定,显然我们可以将相同的连续字符缩在一起.注意到字典序最大的字 ...

  4. JavaScript无提示关闭当前页面窗口,兼容IE/Firefox/Chrome

    <script type="text/javascript" language="javascript"> function fc(){ var b ...

  5. IDEA 官方背景与修改jsp模板以及字体大小

    一.官方背景切换 方法一:先打开file找到Settings  如图: 也可以用快捷方式打开:Ctrl+alt+s  打开 找到Editor点击进入 ,再然后找Color Scheme 可以看到如下图 ...

  6. 微信小程序传值取值的几种方法

    一,列表index下的取值 实现方式是:data-index="{{index}}"挖坑及e.currentTarget.dataset.index来填坑即可 1.1生成值 < ...

  7. Codeforces Round #513 (rated, Div. 1 + Div. 2)

    前记 眼看他起高楼:眼看他宴宾客:眼看他楼坍了. 比赛历程 开考前一分钟还在慌里慌张地订正上午考试题目. “诶这个数位dp哪里见了鬼了???”瞥了眼时间,无奈而迅速地关去所有其他窗口,临时打了一个缺省 ...

  8. Linux-Mysql8.0

    Mysql8.0.12 基本操作 解释 命令 安装服务端 yum install mysql-community-server 启动 service mysqld start/restart 停止 s ...

  9. Oracle 数据库常用SQL语句(2)查询语句

    一.SQL基础查询 1.select语句 格式:select 字段 from 表名; 2.where 用于限制查询的结果. 3.查询条件 > < >= <= = != 4.与 ...

  10. 如何用纯 CSS 创作一个文本淡入淡出的 loader 动画

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/ERwpeG 可交互视频 ...