[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. TFS2018 找不到JRE 错误

    配置TFS 2018 server configurion 报错 : Search requires Oracle Server JRE 7 Update 55 or higher or JRE 8 ...

  2. PSNR

    PSNR,峰值信噪比,通常用来评价一幅图像压缩后和原图像相比质量的好坏,当然,压缩后图像一定会比原图像质量差的,所以就用这样一个评价指标来规定标准了.PSNR越高,压缩后失真越小.这里主要定义了两个值 ...

  3. exportfs: /mnt/demo requires fsid= for NFS export

    解决方法:/mnt/demo 10.0.1.57(fsid=0,rw,async) //加入fsid=0参数就可.

  4. 《队长说得队》【Alpha】Scrum meeting 5

    项目 内容 这个作业属于哪个课程 >>2016级计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里 >>实验十二 团队作业8:软件测试与ALPHA冲刺 团队名称 ...

  5. 【转】MFC 程序入口和执行流程

    一 MFC程序执行过程剖析 1)我们知道在WIN32API程序当中,程序的入口为WinMain函数,在这个函数当中我们完成注册窗口类,创建窗口,进入消息循环,最后由操作系统根据发送到程序窗口的消息调用 ...

  6. UNIX 是啥?!和Linux什么关系?

    操作系统有两大阵营,一边是基于微软 Windows NT 的操作系统,一边是由UNIX衍生下来的操作系统. Linux, Mac OS X, Android, iOS, Chrome OS甚至路由器上 ...

  7. c++ 函数指针应用,定义一个方法,传入两个参数和一个函数指针,并返回结果

    #include <iostream> #include <string> using namespace std; double add(double x, double y ...

  8. 第一本C语言笔记(上)

    1. 一般地源程序文件到可执行程序文件经过如下四步: 预处理 -- 头文件内容插入.宏替换.删注释(#include.#define) 编译 -- 把预处理过的源文件编程汇编文件 .c -> . ...

  9. centos7 killall 命令

    centos7精简安装后,使用中发现没有killall命令. 安装这个包即可: yum install psmisc

  10. ACM-ICPC 2018 徐州赛区网络预赛 H. Ryuji doesn't want to study

    262144K   Ryuji is not a good student, and he doesn't want to study. But there are n books he should ...