两题都是树分治。

  1758这题可以二分答案avgvalue,因为avgvalue=Σv(e)/s,因此二分后只需要判断Σv(e)-s*avgvalue是否大于等于0,若大于等于0则调整二分下界,否则调整二分上界。假设一棵树树根为x,要求就是经过树根x的最大答案,不经过树根x的可以递归求解。假设B[i]为当前做到的一颗x的子树中的点到x的距离为i的最大权值,A[i]为之前已经做过的所有子数中的点到x的距离为i的最大权值(这里的权值是Σv(e)-i*avgvalue),那么对于当前子树的一个距离i,可以从之前处理的子树中取到树根x距离为L-i到U-i权值中最大的那个,判断B[i]+max(A[L-i],A[U-i])是否大于等于0,这里max(A[L-i],A[U-i])可以用一个单调队列求,每处理完一颗子树用B数组更新A数组。

2599数据范围在讨论里,比较简单。

代码:

 //bzoj1758
#include<cstdio>
#include<algorithm>
#include<map>
#include<cstring>
#include<vector>
#include<cmath>
#include<string>
#define N 500010
#define M 1010
using namespace std;
double ans,A[N],B[N],P;
int AS,BS;
int pre[N],p[N],tt[N],ww[N],dp,n,L,U,a,b,c,father[N],s[N],flag[N],tmproot,i,j,l,r,f[N];
double left,right,mid;
void link(int x,int y,int z)
{
dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;ww[dp]=z;
}
void getroot(int x,int fa,int sum)
{
int i,f=;
i=p[x];
father[x]=fa;
s[x]=;
while (i)
{
if ((tt[i]!=fa)&&(!flag[tt[i]]))
{
getroot(tt[i],x,sum);
s[x]=s[x]+s[tt[i]];
if (s[tt[i]]>sum/) f=;
}
i=pre[i];
}
if (sum-s[x]>sum/) f=;
if (f==) tmproot=x;
}
void dfs(int x,int fa,int deep,double value)
{
int i;
i=p[x];
B[deep]=max(B[deep],value-mid*double(deep));
BS=max(deep,BS);
while (i)
{
if ((tt[i]!=fa)&&(!flag[tt[i]]))
dfs(tt[i],x,deep+,value+ww[i]);
i=pre[i];
}
}
void work(int x,int sum)
{
int i,root,ti,ff;
getroot(x,,sum);
root=tmproot;
flag[root]=;
i=p[root];
while (i)
{
if (!flag[tt[i]])
{
if (father[root]!=tt[i])
work(tt[i],s[tt[i]]);
else
work(tt[i],sum-s[root]);
}
i=pre[i];
}
//----------------------------------
left=;right=;ti=;
while (ti<=)
{
ti++;
mid=(left+right)/;
ff=;
for (i=;i<=AS;i++)
A[i]=P;AS=;
i=p[root];
while (i)
{
if (!flag[tt[i]])
{
for (j=;j<=BS;j++)
B[j]=P;BS=;
dfs(tt[i],,,ww[i]);
r=;l=;
for (j=min(U-,AS);j>=L;j--)
{
r++;f[r]=j;
while ((l<r)&&(A[f[r]]>=A[f[r-]]))
{
f[r-]=f[r];
r--;
}
}
for (j=;j<=BS;j++)
{ if ((L<=j)&&(j<=U))
if (B[j]>=) ff=; while ((l<=r)&&(f[l]+j>U)) l++;
if (L-j>)
{
r++;f[r]=L-j;
while ((l<r)&&(A[f[r]]>=A[f[r-]]))
{
f[r-]=f[r];
r--;
}
if (A[f[l]]+B[j]>=) ff=;
}
}
for (j=;j<=BS;j++)
A[j]=max(A[j],B[j]);
AS=max(AS,BS);
}
if (ff) break;
i=pre[i];
} if (ff) left=mid;else right=mid;
}
ans=max(ans,left);
flag[root]=;
}
int main()
{
scanf("%d",&n);
scanf("%d%d",&L,&U);
P=;
P=-P*P;
for (i=;i<=n-;i++)
{
scanf("%d%d%d",&a,&b,&c);
link(a,b,c);
link(b,a,c);
}
for (i=;i<=n;i++)
{
A[i]=P;
B[i]=P;
}
ans=;
work(,n);
printf("%.3lf",ans);
}
 //bzoj2599
#include<cstdio>
#include<algorithm>
#include<map>
#include<cstring>
#include<vector>
#include<cmath>
#include<string>
#define N 1000010
#define M 1010
#define P 1000000007
using namespace std;
int i,j,p[N],tt[N],s[N],father[N],ww[N],pre[N],tmproot,n,m;
int dp,flag[N],a,b,c,f[N],g[N],AS,BS,A[N],B[N],ans;
void link(int x,int y,int z)
{
dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;ww[dp]=z;
}
void getroot(int x,int fa,int sum)
{
int i,f=;
i=p[x];
father[x]=fa;
s[x]=;
while (i)
{
if ((tt[i]!=fa)&&(!flag[tt[i]]))
{
getroot(tt[i],x,sum);
s[x]=s[x]+s[tt[i]];
if (s[tt[i]]>sum/) f=;
}
i=pre[i];
}
if (sum-s[x]>sum/) f=;
if (f==) tmproot=x;
}
void dist(int x,int fa,int deep,int value)
{
int i;
i=p[x];
if (value<=m)
{
if (g[value]==0x37373737)
{
BS++;
B[BS]=value;
}
g[value]=min(g[value],deep);
}
else
return;
while (i)
{
if ((tt[i]!=fa)&&(!flag[tt[i]]))
dist(tt[i],x,deep+,value+ww[i]);
i=pre[i];
} }
void work(int x,int sum)
{
int i,root;
getroot(x,,sum);
root=tmproot;
flag[root]=;
i=p[root];
while (i)
{
if (!flag[tt[i]])
{
if (tt[i]==father[root])
work(tt[i],sum-s[root]);
else
work(tt[i],s[tt[i]]);
}
i=pre[i];
}
//-----------------------------
for (i=;i<=AS;i++)
f[A[i]]=0x37373737;AS=;
i=p[root];
while (i)
{
if (!flag[tt[i]])
{
for (j=;j<=BS;j++)
g[B[j]]=0x37373737;BS=;
dist(tt[i],,,ww[i]);
for (j=;j<=BS;j++)
ans=min(ans,g[B[j]]+f[m-B[j]]);
for (j=;j<=BS;j++)
if (f[B[j]]==0x37373737)
{
AS++;A[AS]=B[j];
}
for (j=;j<=BS;j++)
f[B[j]]=min(f[B[j]],g[B[j]]);
}
i=pre[i];
}
flag[root]=;
}
int main()
{
scanf("%d%d",&n,&m);
for (i=;i<=n-;i++)
{
scanf("%d%d%d",&a,&b,&c);
a++;b++;
link(a,b,c);
link(b,a,c);
}
for (i=;i<=m;i++)
{
f[i]=0x37373737;
g[i]=f[i];
}
ans=0x37373737;
work(,n);
if (ans!=0x37373737)
printf("%d",ans);
else
printf("-1");
}

bzoj1758 [Wc2010]重建计划 & bzoj2599 [IOI2011]Race的更多相关文章

  1. BZOJ1758: [Wc2010]重建计划

    题解: 这题我居然做了一星期?... 平均值的极值其实也可以算是一种分数规划,只不过分母上b[i]=1 然后我们就可以二分这个值.类似与 HNOI最小圈 如果没有 链的长度的限制的话,我们直接两遍df ...

  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. [bzoj2599][IOI2011]Race——点分治

    Brief Description 给定一棵带权树,你需要找到一个点对,他们之间的距离为k,且路径中间的边的个数最少. Algorithm Analyse 我们考虑点分治. 对于子树,我们递归处理,所 ...

随机推荐

  1. CC2540 USB DONGLE 使用 BTool 调试BLE 说明

    一.Btool软件界面介绍 首先您要将USBDONGLE插入电脑的USB口,然后打开双击打开Btool软件,打开后如下图所示: 在安装驱动的教程中,我们已经记住了我们的USB DONGLE的串口号,在 ...

  2. Bluetooth Security Manager

    一.概念     The Security Manager defines methods of pairing and key distribution, a protocol for those ...

  3. Visual Mingw

    Visual-MinGW 是一个专门为MinGW所设计的IDE.如果,你曾经用过VC++ 6.0这个IDE,你的第一感觉就是,Visual-MinGW和VC++ 6.0非常相似.所以,对于曾经用惯VC ...

  4. 关于TCP传输速率的测量方法

    人们非常关心下载速度,对于使用非包月宽带以及使用付费CDN的用户而言,这是典型的拿钱买时间的行为,我支付的费用越高,希望的下载速度越快,所使用的累积带宽越大.关于各种测速方法也是汗牛充栋了,本文介绍一 ...

  5. JS控制flash的播放

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...

  6. 用代码调用Storyboard里面的viewController

    今天在帮助群里的一个朋友弄pop事件,在他那边,当前的viewcontroller,不能pop出去. 初步估计,他的ViewController层级多,他自己没有理清. 因为pushViewContr ...

  7. 用JQuery给图片添加鼠标移入移出事件

    $("#addLineImg").mouseover( function(){ $("#addLineImg").attr("src",&q ...

  8. Spring第13篇—–Spring整合Hibernate之声明式事务管理

    不容置疑的我们可以知道Spring的事务管理是通过AOP(AOP把我们的事务管理织入到我们的业务逻辑里面了)的方式来实现的,因为事务方面的代码与spring的绑定并以一种样板式结构使用.(面向切面编程 ...

  9. centos vmware centos6.6 64位 kvm虚拟化安装配置 第四十二节课

    centos vmware centos6.6 64位 kvm虚拟化安装配置     第四十二节课 上半节课 下半节课 f

  10. node.js render模板

    在用node组织前端架构和后端的时候,如果不用nginx做反向代理,则会考虑怎么样render模板. 在现有的项目中没有以下几种方式render模板: 1.将.html当做静态文件,如果url定位到哪 ...