【bzoj1758】[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
题解:
好一个扫把树……长见识长见识。
显然二分答案+树的点分治。每次遍历一棵子树来得到$dis$数组,表示同一路径数的最大权值,然后再存一个之前遍历子树的桶,含义与$dis$一样,但是要注意从小到大处理每棵子树。扫把树……卡死人。
顺便一提,bzoj不会爆栈。
(空行比较多,所以显得很长……)
1 #define Troy 09/30/2017 2 3 #define inf 0x7fffffff 4 5 #include <bits/stdc++.h> 6 7 using namespace std; 8 9 typedef long long ll; 10 11 const int N=500100; 12 const double eps=1e-4; 13 14 inline int read(){ 15 int s=0,k=1;char ch=getchar(); 16 while(ch<'0'|ch>'9') ch=='-'?k=-1:0,ch=getchar(); 17 while(ch>47&ch<='9') s=s*10+(ch^48),ch=getchar(); 18 return s*k; 19 } 20 21 struct edges{ 22 int v;ll w;edges *last; 23 }edge[N<<1],*head[N];int cnt; 24 25 inline void push(int u,int v,ll w){ 26 edge[++cnt]=(edges){v,w,head[u]};head[u]=edge+cnt; 27 } 28 29 int n,up,low,tot,top,root,size[N],heavy[N],T[N],Tdis[N],part,from; 30 ll t[N],dis[N]; 31 bool vis[N]; 32 double ans,maxr; 33 34 inline void dfs(int x,int fa,int deep){ 35 size[x]=1; 36 heavy[x]=0; 37 for(edges *i=head[x];i;i=i->last)if(i->v!=fa&&(!vis[i->v])){ 38 dfs(i->v,x,deep+1); 39 size[x]+=size[i->v]; 40 heavy[x]=max(size[i->v],heavy[x]); 41 } 42 heavy[x]=max(heavy[x],tot-size[x]); 43 if(heavy[x]<top) 44 top=heavy[x],root=x; 45 } 46 47 inline void calc(int x,int fa,ll d,int lens){ 48 if(lens>up) return ; 49 if(Tdis[lens]!=part){ 50 Tdis[lens]=part; 51 dis[lens]=d; 52 }else 53 dis[lens]=max(dis[lens],d); 54 for(edges *i=head[x];i;i=i->last) if(i->v!=fa&&(!vis[i->v])){ 55 calc(i->v,x,d+i->w,lens+1); 56 } 57 } 58 59 inline void get_new(int x,int fa,ll d,int lens){ 60 if(lens>up) return; 61 if(T[lens]!=T[0]) 62 T[lens]=T[0],t[lens]=d; 63 else 64 t[lens]=max(t[lens],d); 65 from=max(from,lens); 66 for(edges *i=head[x];i;i=i->last) if(i->v!=fa&&(!vis[i->v])){ 67 get_new(i->v,x,d+i->w,lens+1); 68 } 69 } 70 71 int q[N]; 72 double nq[N]; 73 74 inline bool Judge(double x){ 75 int l=0,r=0; 76 int pos=min(up-1,from); 77 bool flag=1; 78 while(pos>=low){ 79 if(T[pos]!=T[0]){ 80 pos--;continue; 81 } 82 while(r>l&&nq[r-1]<t[pos]-x*pos) 83 r--; 84 nq[r]=t[pos]-x*pos; 85 q[r++]=pos; 86 pos--; 87 } 88 for(int i=low-pos;i<=up;i++){ 89 if(Tdis[i]!=part) break; 90 if(pos>=0&&i+pos>=low&&T[pos]==T[0]){ 91 while(r>l&&nq[r-1]<t[pos]-x*pos) 92 r--; 93 nq[r]=t[pos]-x*pos; 94 q[r++]=pos; 95 } 96 while(l<r&&q[l]+i>up) 97 l++; 98 pos--; 99 if(l<r&&nq[l]+dis[i]-i*x>=0) 100 return true; 101 } 102 return false; 103 } 104 105 struct node{ 106 int v,w; 107 friend bool operator <(node x,node y){ 108 return size[x.v]<size[y.v]; 109 } 110 }sons[N]; 111 112 113 inline void solve(int u){ 114 tot=size[u]; 115 top=inf; 116 dfs(u,u,0); 117 vis[root]=true; 118 T[0]++; 119 from=1; 120 int cc=0; 121 for(edges *i=head[root];i;i=i->last)if(!vis[i->v]){ 122 cc++; 123 sons[cc].v=i->v; 124 sons[cc].w=i->w; 125 } 126 sort(sons+1,sons+1+cc); 127 for(int i=1;i<=cc;i++){ 128 if(i>1){ 129 part++; 130 calc(sons[i].v,0,sons[i].w,1); 131 double l=ans,r=maxr,mid; 132 while(l<r-eps){ 133 mid=(l+r)/2; 134 if(Judge(mid)) l=mid; 135 else r=mid; 136 } 137 ans=l; 138 } 139 if(i<cc) 140 get_new(sons[i].v,0,sons[i].w,1); 141 } 142 for(edges *i=head[root];i;i=i->last) if(!vis[i->v]) 143 solve(i->v); 144 } 145 146 int main(){ 147 n=read(); 148 low=read(),up=read(); 149 for(int i=1,u,v,w;i<n;i++){ 150 u=read(),v=read(),w=read(); 151 push(u,v,w),push(v,u,w); 152 maxr=max(maxr,w+0.0); 153 } 154 size[1]=n; 155 solve(1); 156 printf("%.3lf\n",ans); 157 }
转载于:https://www.cnblogs.com/Troywar/p/7614422.html
【bzoj1758】[Wc2010]重建计划相关推荐
- bzoj1758 [Wc2010]重建计划
http://www.elijahqi.win/2018/01/20/bzoj1758/ Description Input 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U, ...
- Bzoj1758: [Wc2010]重建计划
题面 传送门 Sol 题意就是给你一棵树,有边权 求边数在[L,U][L,U][L, U]内的一条路径,使得边权和除以边数最大,输出这个最大值 二分答案+点分治+单调队列 二分一个答案midmidmi ...
- [luogu 4292][bzoj 1758][WC2010] 重建计划(点分治 + dp + 单调队列优化 + 启发式合并)
[WC2010]重建计划 problem solution code problem 洛谷指路 solution 一看那个道路平均价值的式子:AvgValue=∑e∈Sv(e)∣S∣\text{Avg ...
- [Luogu P4292] [BZOJ 1758] [WC2010]重建计划
BZOJ 传送门 洛谷传送门 题目描述 X国遭受了地震的重创, 导致全国的交通近乎瘫痪,重建家园的计划迫在眉睫.X国由NNN个城市组成, 重建小组提出,仅需建立N−1" role=" ...
- 点分治问题 ----------- luoguP2942 [WC2010]重建计划 [点分治 + bfs + 单调队列 + 预处理建树 + 二分 + 01分数规划]
题目链接 解题思路: 1.对于这个Avgvalue=∑e∈sv(e)∣s∣Avgvalue = \frac{\sum_{e\in s}v(e)}{|s|}Avgvalue=∣s∣∑e∈sv(e) ...
- 【BZOJ1758】重建计划,点分治+单调队列
Time:2016.08.21 Author:xiaoyimi 转载注明出处谢谢 传送门 思路: UPD 2017.1.18 之前的思路删掉了,因为写的太烂,纯属放屁 刚刚知道新加了一组数据,所以原先 ...
- 1758: [Wc2010]重建计划(TLE)
链接 http://www.lydsy.com/JudgeOnline/problem.php?id=1758 题解? 首先说明这道题我没过. 那为啥要写题解? 因为我确实写的正解啊. 不就是先二分答 ...
- 【WC2010】重建计划(分数规划+长链剖分)
长链剖分 因为有很多巨佬只是讲了一下大致的做法,并没有详细地解释如何维护,所以就有了这篇题解.巨佬们都不屑于详细写,我太弱了/kk 首先先对原树进行长链剖分. 先讲一些定义: 一条路径的权值和指的是这 ...
- 洛谷P4292:重建计划(点分治、单调队列)
解析 第一眼:Wow这么水的黑?? 然后写了一发二分套线段树的3log代码上去 T到飞起,只有40- 无奈瞅了一眼标签:单调队列 对啊 于是又写了一个上去 20 - 好啊 然后就摆烂了 qwq 果然黑 ...
最新文章
- GitHub代码一键转VS Code:只需+1s
- Scrapy框架--使用cookie
- SpringSecurity-eclipse
- python 如何用指数函数拟合数据?(2020年新型冠状病毒感染人数预测)
- websocket vs keep-live
- 【Linux】一步一步学Linux——pidof命令(122)
- qemu 规范路径_基于qemu-riscv64模拟器运行debian
- 参数化测试 junit_使用JUnit 5进行更清洁的参数化测试
- java递减_关于Java中递增和递减运算符的有趣事实
- spark pineline流水线+聚类评估函数 小结
- hive优化--增加减少map数
- C4996: 'inet_addr': Use inet_pton() or InetPton() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS
- 百度云下载插件,创建链接,脚本管理,百度网盘快速下载
- 地震数据爬取——Scrapy爬虫框架应用
- 智慧水务管理系统提升城市水务管理智慧化水平
- c语言编码rna翻译,哪位大牛有哈夫曼编码的C语言源程序,麻烦帮帮忙啦!
- 基因表达式编程(GEP)自学 第【3】天 Python 实现
- 无线网络设置的dns服务器,DNS怎么设置才能上网
- 广州市长温国辉:用“加减乘除法”发展民营经济
- 怎样提高学生计算机应用能力,如何提高中职学生计算机应用能力