两题都是树分治。

  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. java JDK8 学习笔记——第15章 通用API

    第十五章 通用API 15.1 日志 15.1.1 日志API简介 1.java.util.logging包提供了日志功能相关类与接口,不必额外配置日志组件,就可在标准Java平台使用是其好处.使用日 ...

  2. SqlServer数据组织结构

    page页 每个页面8KB,连续的8个页面称之为一个区extents, 如:2.18MB的一个DB的区大约有 2.18 MB (2,293,760 字节)=2,293,760b/8kb=280个页面= ...

  3. php---JSON和JSONP

    JSON和JSONP (含jQuery实例)(share) 来源:http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jque ...

  4. iOS面试题 02

    在面试的时候,面试官问我,“你对内存管理了解的多吗?” 我忘了当时是怎么回答的了,但是,肯定是一时没想起来怎么回答. 1.谁创建谁释放 2.autoreleasepool 3.retain,copy, ...

  5. Selenium2学习-024-WebUI自动化实战实例-022-网站不同分辨率下页面样式展示兼容性问题解决方案 -- 设置浏览器显示区域大小(无人值守,节约测试成本的福音,BOSS 最爱)

    在 Web UI 自动化测试的过程中,通常会测试页面在不同分辨率下的显示效果,即在不同大小的显示器上全屏浏览器后的页面展示,此种测试方法需要购置不同大小的显示器,或者频繁的设置屏幕分辨率,不仅浪费了大 ...

  6. [转]ANDROID L——Material Design详解(动画篇)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 转自:http://blog.csdn.net/a396901990/article/de ...

  7. imx6 RGB LCD

    imx6dl需要支持lcd接口的屏,imx6dl的datasheet并没有明确的说明lcd相关的配置,只在Display Content Integrity Checker (DCIC)一章中介绍.本 ...

  8. js获取框架(IFrame)的内容

    <frameset id="fr" rows="50%,50%">      <frame name="up" id=&q ...

  9. iOS 并发编程之 Operation Queues

    现如今移动设备也早已经进入了多核心 CPU 时代,并且随着时间的推移,CPU 的核心数只会增加不会减少.而作为软件开发者,我们需要做的就是尽可能地提高应用的并发性,来充分利用这些多核心 CPU 的性能 ...

  10. Speed-BI 图表功能:服装订货与销售匹配分析

    在作为一个买手我们根据对市场的预测,订了一批的货回来. 我们总会有一个疑问:我的订货与市场的需求是一致的吗?是否出现了较大偏差.这时我们通过分析两个指标:订货占比与销售占比的差异,进行订货与销售的匹配 ...