[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. 在ProgressBar控件中显示进度百分比

    实现效果: 知识运用: ProgressBar控件的Value属性 //控件的当前值 Maximum属性 //ProgressBar正在使用的范围的上限 PerformStep方法 //按照Step属 ...

  2. JavaScript操作DOM

    1.DOM对象简介: 什么是DOM:(Document Object Model) 译为文档对象模型,是 HTML 和 XML 文档的编程接口.   2.DOM HTML 节点树:指的是DOM中为操作 ...

  3. Render渲染函数和JSX

    1.Render函数:render是用来替换temlate的,需要更灵活的模板的写法的时候,用render. 官网API地址:https://cn.vuejs.org/v2/guide/render- ...

  4. PAT (Basic Level) Practise (中文)- 1014. 福尔摩斯的约会 (20)

    http://www.patest.cn/contests/pat-b-practise/1014 1014. 福尔摩斯的约会 (20) 时间限制 50 ms 内存限制 65536 kB 代码长度限制 ...

  5. JQuery EasyUI学习记录(二)

    1.jquery easyUI动态添加选项卡(查看jquery easyUI手册) 1.1 用于动态添加一个选项卡 1.1.1 选中指定的选项卡和判断某个选项卡是否存在 测试代码: <a id= ...

  6. MySql下最好用的数据库管理工具是哪个

    MySql下最好用的数据库管理工具是哪个? 维基上有个很全的列表: https://en.wikipedia.org/wiki/Comparison_of_database_tools   1. ph ...

  7. C语言中的32个关键字

    C语言中的32个关键字 数据类型关键字(12个) (1)     char:声明字符型变量或函数 (2)     double:声明双精度变量或函数 (3)     enum:声明美剧类型 (4)   ...

  8. asp发送短信验证码 pst方式

    <script language="jscript" runat="server">  Array.prototype.get = function ...

  9. python基本数据类型和简单用法

    一.int 整形范围 How Big Is an int? In Python2, the size of an int was limited to 32 bits, which is enough ...

  10. python3 简单服务器监控,自动发送邮件

    import smtplibfrom email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipartimpo ...