bzoj 1758: [Wc2010]重建计划
Description

Input
第 一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai,Bi,Vi分别表示道路(Ai,Bi),其价值为Vi 其中城市由1..N进行标号
Output
输出最大平均估值,保留三位小数
Sample Input
2 3
1 2 1
1 3 2
1 4 3
Sample Output
HINT
N<=100000,1<=L<=U<=N-1,Vi<=1000000 新加数据一组 By leoly,但未重测..2016.9.27
Source
这个WC题与一道WG的题贼像!!!
然后这题的套路据说又与wfj_2048大佬的middle贼像!!!
这种求平均值和中位数的套路就是二分,具体对于这个题来说二分一个平均值,把所有的边的边权减去mid
剩下的就是判断是否有一条长度在[L,R]间的路权值大于0;也就是说求长度在[L,R]间的权值最大的边
我个傻逼想到这里就GG了,然后就只能堕落了,于是去翻了翻LightGod的博客,Orz,太厉害了
对于一个点,一条路径只有经过这个点,或不经过这个点两种情况,不经过这个点的情况就往下递归,我们考虑经过这个点的情况
对于一条简单路径,他必定是在这个点的子树中选取两条不在同一子树中的路径进行相加
于是这个东西可以用单调队列来维护一个滑动窗口,(ANS[i]记录长度为i的权值最大的路径)
具体做法是这样:
我们考虑这个点的每个儿子管理的连通块(在每个儿子getdis的时候把该儿子管辖下的连通块中每个长度的权值最大值记录下来)
那么我们枚举处理该儿子的记录下来的边(每个长度的权值最大的边),假设长度为i,那么对于其他子树中长度的取值范围就是[L-i,R-i];
然后我们用普通单调队列的处理,处理完后这个儿子后再拿这个儿子的所有边去更新ANS.
对于每个点可以O(size)维护该点的最优值;
然后这个题就打完了...然后调了好久,是一个函数名打错了
附上代码:
// MADE BY QT666
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<queue>
#include<set>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#define lson num<<1
#define rson num<<1|1
#define deepmaxlen dml
using namespace std;
typedef long long ll;
const int N=500050;
const int Inf=2147483647;
const double eps=1e-5;
int gi()
{
int x=0,flag=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*flag;
}
int head[N],to[N],nxt[N];
int size[N],f[N],deep[N],rt[N],vis[N],q[N];
double dml[N],ANS[N],ans=-Inf,c[N],dis[N];
int SIZE,root,cnt,tot,tot2,L,R,M_DEP,n;
struct data{
int id,dep;
}son[N];
bool cmp(data a,data b){
return a.dep<b.dep;
}
void lnk(int x,int y,int v){
to[++cnt]=y,c[cnt]=(double)v,nxt[cnt]=head[x],head[x]=cnt;
to[++cnt]=x,c[cnt]=(double)v,nxt[cnt]=head[y],head[y]=cnt;
}
void getroot(int x,int fa){
size[x]=1;f[x]=0;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(!vis[y]&&y!=fa){
getroot(y,x);
size[x]+=size[y];
f[x]=max(f[x],size[y]);
}
}
f[x]=max(f[x],SIZE-size[x]);
if(f[x]<f[root]) root=x;
}
void get_maxdis(int x,int fa){
dml[deep[x]]=max(dml[deep[x]],dis[x]);
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(y!=fa&&!vis[y]){
dis[y]=dis[x]+c[i];
get_maxdis(y,x);
}
}
}
void get_deep(int x,int fa){
;M_DEP=max(M_DEP,deep[x]);
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(y!=fa&&!vis[y]){
deep[y]=deep[x]+1;
get_deep(y,x);
}
}
}
void work(int x){
rt[++tot]=x;vis[x]=1;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(!vis[y]){
root=0;SIZE=size[y];getroot(y,0);
work(root);
}
}
}
void work2(int x){
tot2++;x=rt[tot2];int cnt2=0;vis[x]=1;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(!vis[y]){
dis[y]=c[i];
M_DEP=deep[y]=1;get_deep(y,x);
son[++cnt2]=(data){y,M_DEP};
}
}
int last=0;
sort(son+1,son+1+cnt2,cmp);
for(int i=1;i<=cnt2;i++){
get_maxdis(son[i].id,x);
int st=1,ed=0,l=last,r=last;
for(int j=1;j<=son[i].dep;j++){
while(l>=0&&l>=L-j){
while(st<=ed&&ANS[q[ed]]<ANS[l]) ed--;
q[++ed]=l--;
}
for(;r>=0&&r+j>R;r--) while(st<=ed&&q[st]>=r) st++;
if(st<=ed) ans=max(ans,dml[j]+ANS[q[st]]);
}
for(int j=1;j<=son[i].dep;j++) ANS[j]=max(ANS[j],dml[j]),dml[j]=(double)-Inf;
last=max(last,son[i].dep);
}
for(int i=1;i<=last;i++) ANS[i]=(double)-Inf;
if(ans>=0) return;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(!vis[y]){
work2(y);
}
}
}
bool check(double mid){
for(int i=1;i<=cnt;i++) c[i]-=mid;
for(int i=1;i<=n;i++) vis[i]=0,dis[i]=0,deep[i]=0;ans=-Inf;
tot2=0;work2(rt[1]);
for(int i=1;i<=cnt;i++) c[i]+=mid;
return ans>=0;
}
int main(){
n=gi();L=gi();R=gi();
int x,y,z;
for(int i=1;i<n;i++){
x=gi(),y=gi(),z=gi();lnk(x,y,z);
}
for(int i=1;i<=n;i++) dml[i]=ANS[i]=-Inf;
root=0;f[0]=Inf;SIZE=n;getroot(1,0);work(root);
double l=0,r=1000000;
while(r-l>eps){
double mid=(l+r+eps)/2;
if(check(mid))l=mid;
else r=mid-eps;
}
printf("%.3lf",l);
}
bzoj 1758: [Wc2010]重建计划的更多相关文章
- bzoj 1758 [Wc2010]重建计划 分数规划+树分治单调队列check
[Wc2010]重建计划 Time Limit: 40 Sec Memory Limit: 162 MBSubmit: 4345 Solved: 1054[Submit][Status][Disc ...
- BZOJ.1758.[WC2010]重建计划(分数规划 点分治 单调队列/长链剖分 线段树)
题目链接 BZOJ 洛谷 点分治 单调队列: 二分答案,然后判断是否存在一条长度在\([L,R]\)的路径满足权值和非负.可以点分治. 对于(距当前根节点)深度为\(d\)的一条路径,可以用其它子树深 ...
- BZOJ 1758: [Wc2010]重建计划 [暂时放弃]
今天晚上思维比较乱,以后再写写吧#include <iostream> #include <cstdio> #include <cstring> #include ...
- BZOJ 1758: [Wc2010]重建计划 01分数规划+点分治+单调队列
code: #include <bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in", ...
- BZOJ1758: [Wc2010]重建计划
题解: 这题我居然做了一星期?... 平均值的极值其实也可以算是一种分数规划,只不过分母上b[i]=1 然后我们就可以二分这个值.类似与 HNOI最小圈 如果没有 链的长度的限制的话,我们直接两遍df ...
- 洛谷 P4292 [WC2010]重建计划 解题报告
P4292 [WC2010]重建计划 题目描述 \(X\)国遭受了地震的重创, 导致全国的交通近乎瘫痪,重建家园的计划迫在眉睫.\(X\)国由\(N\)个城市组成, 重建小组提出,仅需建立\(N-1\ ...
- [WC2010]重建计划 长链剖分
[WC2010]重建计划 LG传送门 又一道长链剖分好题. 这题写点分治的人应该比较多吧,但是我太菜了,只会长链剖分. 如果你还不会长链剖分的基本操作,可以看看我的长链剖分总结. 首先一看求平均值最大 ...
- BZOJ 1758 / Luogu P4292 [WC2010]重建计划 (分数规划(二分/迭代) + 长链剖分/点分治)
题意 自己看. 分析 求这个平均值的最大值就是分数规划,二分一下就变成了求一条长度在[L,R]内路径的权值和最大.有淀粉质的做法但是我没写,感觉常数会很大.这道题可以用长链剖分做. 先对树长链剖分. ...
- 【bzoj1758】[Wc2010]重建计划
Description Input 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案, ...
随机推荐
- c语言的枚举(遍历枚举)与数据类型总结
一.枚举的概念 枚举是C语言中的一种基本数据类型,并不是构造类型,它可以用于声明一组常数.当一个变量有几个固定的可能取值时,可以将这个变量定义为枚举类型. 比如,你可以用一个枚举类型的变量来表示季节, ...
- C/C++中如何接收return返回来的数组元素
我们知道return语句作为被调用函数的结束,返回给调用者函数值.一般来说,是返回一个函数值,像一个int, double,char等类型的数据,当然也可以是他们的指针.但是当我们遇到要返回很多数怎么 ...
- jQuery中使用$.each()遍历后台响应的json字符串问题
今天在做练习项目的时候,使用$.each()方法遍历后台传过来的json字符串时,chrome浏览器中发现如下问题 Cannot use 'in' operator to search for 'l ...
- sql server 2008 r2 登陆时显示无法打开默认的数据库
解决! 第一步: 远程其他服务器的数据库能连上,本地的数据库某个用户名就是打不开,一开始以为是用户名或者密码错误, 后来用sqlcmd dos命令 -S . -U an -P sa 的方式登陆时可以的 ...
- DIN(Deep Interest Network of CTR) [Paper笔记]
背景 经典MLP不能充分利用结构化数据,本文提出的DIN可以(1)使用兴趣分布代表用户多样化的兴趣(不同用户对不同商品有兴趣)(2)与attention机制一样,根据ad局部激活用户兴趣相关的兴趣(用 ...
- PHP基础 windows环境下安装Apache Mysql PHP
本篇文章主要是讲一下我自己安装wamp环境的一些步骤和见解,前方多图预警,慎入!!!!! PHP运行环境 : Linux下的三种安装方式:源码包安装.rpm包安装.集成环境安装(lnmp) wind ...
- windows添加默认路由
由于GW的原因,我们无法使用强大的google,身为技术屌丝,这是不能容忍的,于是乎使用了VPN,但是VPN连上之后,悲剧发生了,我的服务器连不上了,怎么整 原来一切都是很简单,在windows上添加 ...
- 【POJ3254】Corn Fields
http://poj.org/problem?id=3254 题意:给你一块n*m(0<n,m<=12)的地图,其中有的方格是肥沃的(用1表示),有的方格是贫瘠的(用0表示).现在约翰要在 ...
- Android用户登录机制安全性的一些思考
1 client要做到安全存贮数据非常难,通过反编译和强攻.仅仅要有心,差点儿都能够破解. 2 服务端相对安全. 3 结合以上两点,推出能做的点是控制灾难规模.每次破解一个client仅仅能针对 ...
- UILabel 的使用
直接上代码: /* UILabel 使用 */ UILabel *aLable = [[UILabel alloc] initWithFrame:self.window.bounds]; aLable ...