题解:

这题我居然做了一星期?。。。

平均值的极值其实也可以算是一种分数规划,只不过分母上b[i]=1

然后我们就可以二分这个值。类似与 HNOI最小圈

如果没有 链的长度的限制的话,我们直接两遍dfs就可以求出以每个点为起点的最长链,然后看看有没有权值和>0的即可。

但现在链有长度限制。。。

所以膜拜题解。。。

发现我们可以点分治,然后每个节点的合法对象都是一段连续的区间,

当用某个值来更新答案的时候是一个连续的区间。

所以可以单调队列来维护定长的区间最大值问题。

实现的时候好多细节。。。还好卡时过了。。。

注意优化:如果子树节点个数<l就不要递归下去了。

代码:

 #include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define inf 1000000000
#define maxn 200000+5
#define maxm 200000+5
#define eps 1e-10
#define pa pair<int,int>
#define for0(i,n) for(int i=0;i<=(n);i++)
#define for1(i,n) for(int i=1;i<=(n);i++)
#define for2(i,x,y) for(int i=(x);i<=(y);i++)
#define for3(i,x,y) for(int i=(x);i>=(y);i--)
#define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
#define for5(n,m) for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
#define mod 1000000007
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+ch-'';ch=getchar();}
return x*f;
}
int n,ll,rr,mx[],rt,sum,tot,v[maxn],s[maxn],ss[maxn],head[maxn],q[maxn];
double mid,f[maxn],g[maxn];
struct edge{int go,next;double w;}e[*maxn];
bool del[maxn];
inline void add(int x,int y,double w)
{
e[++tot]=(edge){y,head[x],w};head[x]=tot;
e[++tot]=(edge){x,head[y],w};head[y]=tot;
}
inline void getrt(int x,int fa)
{
ss[x]=;s[x]=;
for4(i,x)if(!del[y]&&y!=fa)
{
getrt(y,x);
s[x]+=s[y];
ss[x]=max(ss[x],s[y]);
}
ss[x]=max(ss[x],sum-s[x]);
if(ss[x]<ss[rt])rt=x;
}
inline void get(int x,int fa,int dep,double w)
{
mx[]=max(mx[],dep);
g[dep]=max(g[dep],w);
for4(i,x)if(!del[y]&&y!=fa)get(y,x,dep+,w+e[i].w-mid);
}
bool solve(int x)
{
del[x]=;mx[]=;
for4(j,x)if(!del[y])
{
mx[]=;
get(y,x,,e[j].w-mid);
int l=,r=;
for3(i,rr,)
{
if(rr-i>&&rr-i<=mx[])
{
while(l<=r&&f[rr-i]>f[q[r]])r--;
q[++r]=rr-i;
}
if(i<=mx[])
{
while(l<r&&q[l]+i<ll)l++;
if(q[l]+i>=ll&&f[q[l]]+g[i]>eps)return ;
}
}
mx[]=max(mx[],mx[]);
for1(i,mx[])f[i]=max(f[i],g[i]),g[i]=-inf;
}
for1(i,mx[])f[i]=-inf;
for4(i,x)if(!del[y])
{
sum=s[y];rt=;
getrt(y,);
if(solve(rt))return ;
}
return ;
}
bool check()
{
for1(i,n)del[i]=,g[i]=-inf,f[i]=-inf;
sum=n;ss[rt=]=inf;
getrt(,);
return solve(rt);
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
n=read();
ll=read();rr=read();
double l=0.0,r;
for1(i,n-){int x=read(),y=read();double z=read();r=max(r,z);add(x,y,z);}
while(r-l>1e-)
{
mid=(l+r)/;
if(check())l=mid;else r=mid;
}
printf("%.3f\n",l);
return ;
}

1758: [Wc2010]重建计划

Time Limit: 40 Sec  Memory Limit: 162 MB
Submit: 887  Solved: 314
[Submit][Status]

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

20%的数据,N<=5000
30%的数据,N<=100000,原有方案恰好为一条路径
100%的数据,N<=100000,1<=L<=U<=N-1,Vi<=1000000

BZOJ1758: [Wc2010]重建计划的更多相关文章

  1. bzoj1758 [Wc2010]重建计划 & bzoj2599 [IOI2011]Race

    两题都是树分治. 1758这题可以二分答案avgvalue,因为avgvalue=Σv(e)/s,因此二分后只需要判断Σv(e)-s*avgvalue是否大于等于0,若大于等于0则调整二分下界,否则调 ...

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

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

  3. [BZOJ1758][WC2010]重建计划(点分治+单调队列)

    点分治,对于每个分治中心,考虑求出经过它的符合长度条件的链的最大权值和. 从分治中心dfs下去取出所有链,为了防止两条链属于同一个子树,我们一个子树一个子树地处理. 用s1[i]记录目前分治中心伸下去 ...

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

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

  5. BZOJ1758 WC2010 重建计划 二分答案、点分治、单调队列

    传送门 看到平均数最大,自然地想到二分答案.那么我们的$check$函数就是要求:是否存在一条长度在$[L,U]$的路径,满足其权值和$\geq 0$. 看到长度在$[L,U]$,自然地想到点分治求解 ...

  6. 2019.01.21 bzoj1758: [Wc2010]重建计划(01分数规划+长链剖分+线段树)

    传送门 长链剖分好题. 题意简述:给一棵树,问边数在[L,R][L,R][L,R]之间的路径权值和与边数之比的最大值. 思路: 用脚指头想都知道要01分数规划. 考虑怎么checkcheckcheck ...

  7. 洛谷 P4292 [WC2010]重建计划 解题报告

    P4292 [WC2010]重建计划 题目描述 \(X\)国遭受了地震的重创, 导致全国的交通近乎瘫痪,重建家园的计划迫在眉睫.\(X\)国由\(N\)个城市组成, 重建小组提出,仅需建立\(N-1\ ...

  8. [WC2010]重建计划 长链剖分

    [WC2010]重建计划 LG传送门 又一道长链剖分好题. 这题写点分治的人应该比较多吧,但是我太菜了,只会长链剖分. 如果你还不会长链剖分的基本操作,可以看看我的长链剖分总结. 首先一看求平均值最大 ...

  9. bzoj 1758 [Wc2010]重建计划 分数规划+树分治单调队列check

    [Wc2010]重建计划 Time Limit: 40 Sec  Memory Limit: 162 MBSubmit: 4345  Solved: 1054[Submit][Status][Disc ...

随机推荐

  1. 以a为变量名,给出下列描述的定义

    a)一个整型数(An integer) b) 一个指向整型数的指针(A pointer to an integer) c) 一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to ...

  2. C语言宏定义取得两数的最大值和最小值

    /*本程序时为了验证用宏来做 * 两个数的大小比较的写法*/#include<stdio.h>#define MAX(x,y) ((x)<(y)?(y):(x))#define MI ...

  3. NULL, NUL, EOF, '\0',0区别

    NULL: 定义为0或0L或(void *)0,用于指示一个指针值是空,即什么都不指:'\0': 用且只用字符串结束符;NUL : 0x00,0值字符,可以用于结束ASCII字符串,和'\0'类似,但 ...

  4. [转]Unity3D游戏开发之数据持久化PlayerPrefs的使用

    转自 http://blog.csdn.net/qinyuanpei/article/details/24195977 首先我们来看两段Unity3D中实现数据读写的简单代码吧: //保存数据 Pla ...

  5. [译] ASP.NET 生命周期 – ASP.NET 上下文对象(八)

    使用 HttpResponse 对象 HttpResponse 对象是与 HttpRequest 对象相对应的,用来表示构建中的响应.它当中提供了方法和属性可供我们自定义响应,有一些在使用 MVC 视 ...

  6. Xcode的后缀字母的意思是

    'A'  新增 'D'  删除 'M'  修改 'R'  替代 'C'  冲突 'I'  忽略 '?'  未受控 '!'  丢失,一般是将受控文件直接删除导致

  7. iOS 状态栏管理

    iOS 7 以前:状态栏由 UIApplication 管理 1.隐藏状态栏 : application.statusBarHidden = NO; 2.设置状态栏样式 : application.s ...

  8. 【linux程序设计4th】第三章1

    makefile .PHONY:clean all CC=gcc CFLAGS=-Wall -g ###replace your bin BIN=simple_write simple_read co ...

  9. [转载]async & await 的前世今生

    async 和 await 出现在C# 5.0之后,给并行编程带来了不少的方便,特别是当在MVC中的Action也变成async之后,有点开始什么都是async的味道了.但是这也给我们编程埋下了一些隐 ...

  10. spoj 345

    DP  想了好久  还是看了一下题解.... f[i][j]表示i到j全部合并后的最小花费,f[i][j] = min{f[i][k]+f[k+1][j]+d[i][k]*d[k+1][j]} (i ...