博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【bzoj1758】 Wc2010—重建计划
阅读量:5123 次
发布时间:2019-06-13

本文共 2340 字,大约阅读时间需要 7 分钟。

 (题目链接)

题意

  给出一棵树,每条边有边权,问选出一条长度为$[L,U]$的路径,使得路径上的边权平均数最大是多少。

Solution

  哈哈,爸爸终于过啦。

  首先二分答案,然后路径统计显然点分治,统计答案的时候单调队列维护一下滑动窗口里面的最值。因为要点分治若干次,我们不妨将重心预处理出来,减少常数。

  一定要小心,在点分治处理子树的时候,一定要按照深度从小到大的顺序处理,不然直接被新加的那组扫把型的数据卡掉T_T。

细节

  清空cnt。

代码

// bzoj1758#include
#include
#include
#include
#include
#include
#include
#define LL long long#define LD long double#define eps 1e-4#define inf (1ll<<60)#define Pi acos(-1.0)#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)using namespace std;const int maxn=100010;int n,m,U,L,cnt,head[maxn];struct edge {int to,next,w;}e[maxn<<1];struct data { int num,D; friend bool operator < (data a,data b) {return a.D>b.D;}};namespace NodeDivide { int Dargen,rt,D,maxD,sum,size[maxn],vis[maxn],Sum[maxn],f[maxn],q[maxn],h[maxn]; edge t[maxn]; double ans,deep[maxn],dis[maxn],Dis[maxn]; void link(int u,int v) {t[++cnt]=(edge){v,h[u]};h[u]=cnt;} void dfs(int x,int fa) { size[x]=f[x]=1; for (int i=head[x];i;i=e[i].next) if (e[i].to!=fa && !vis[e[i].to]) { dfs(e[i].to,x); f[x]=max(f[x],size[e[i].to]); size[x]+=size[e[i].to]; } f[x]=max(f[x],sum-size[x]); if (f[x]
T; for (int i=head[x];i;i=e[i].next) if (!vis[e[i].to]) { D=0;deep[e[i].to]=e[i].w; caldeep(e[i].to,x,1); T.push((data){e[i].to,D}); } while (!T.empty()) { data tmp=T.top();T.pop(); caldis(tmp.num,x,1); int l=1,r=0,pl=maxD,pr=maxD; for (int i=1;i<=tmp.D;i++) { for (;pl>-1 && pl>=L-i;pl--) { while (l<=r && Dis[q[r]]-q[r]*res
-1 && pr>U-i;pr--) while (l<=r && q[l]>=pr) l++; if (pl
=L) solve(t[i].to,res); vis[x]=0; } void caldargen(int x,int fa) { vis[x]=1; if (fa) link(fa,x);else Dargen=x; for (int i=head[x];i;i=e[i].next) if (!vis[e[i].to]) { sum=size[e[i].to],rt=0; dfs(e[i].to,x); Sum[rt]=sum; caldargen(rt,x); } vis[x]=0; } void Init() { cnt=0; sum=n;f[rt=0]=1<<30; dfs(1,0);Sum[rt]=sum; caldargen(rt,0); } double main(double res) { ans=-inf; solve(Dargen,res); return ans; }}using namespace NodeDivide;void link(int u,int v,int w) { e[++cnt]=(edge){v,head[u],w};head[u]=cnt; e[++cnt]=(edge){u,head[v],w};head[v]=cnt;}int main() { scanf("%d%d%d",&n,&L,&U); for (int u,v,w,i=1;i
=0) l=mid+eps,ans=mid; else r=mid-eps; } printf("%.3lf",ans); return 0;}

 

转载于:https://www.cnblogs.com/MashiroSky/p/6510054.html

你可能感兴趣的文章
拦截QT关闭窗口的CloseEvent
查看>>
git
查看>>
HDU 1159 Common Subsequence 动态规划
查看>>
冒泡排序 和 归并排序
查看>>
【转】C#之继承
查看>>
jieba库分词
查看>>
BAT批量处理 命令
查看>>
【读书笔记】计算机是怎样跑起来的
查看>>
ApacheCN 数据科学/人工智能/机器学习知识树 2019.2
查看>>
Httpd 使用ip可以访问,localhost和127.0.0.1不能访问
查看>>
类的 三大特性 封装,继承,多态 overload与override的区别
查看>>
Date Picker控件:
查看>>
svn在linux下的使用(svn命令行)ubuntu 删除 新增 添加 提交 状态查询 恢复
查看>>
java处理url中的特殊字符%等
查看>>
你的第一个Django程序
查看>>
Tomcat免安装版的环境变量配置以及Eclipse下的Tomcat配置和测试
查看>>
Unity3D性能优化之Draw Call Batching
查看>>
grafana授权公司内部邮箱登录 ldap配置
查看>>
treegrid.bootstrap使用说明
查看>>
[Docker]Docker拉取,上传镜像到Harbor仓库
查看>>