[BZOJ 2500]幸福的道路 树形dp+单调队列+二分答案
考试的时候打了个树链剖分,而且还审错题了,以为是每天找所有点的最长路,原来是每天起点的树上最长路径再搞事情。。
先用dfs处理出来每个节点以他为根的子树的最长链和次长链。(后面会用到)
然后用类似dp的方法把每个节点的最长路径求出来。
下面是具体解释,请思考
以一个节点为例(w为它与父亲节点道路的权值)
一、如果它父亲节点的最长路径不过它
那么它最长路径等于它父亲最长路径+w(自己画图即可理解,往上走的)
它的次长路径等于它的最长链(只能往下走)
二、如果过它
那么它的最长路径有两种可能
①它的最长链
②它父亲的次长路径+w
如果①优,那么它最长路径为①,次长路径为max(它的次长链,②)
如果②优,那么它最长路径为②,次长路径为①
很好理解吧。。。
然后让求最大值与最小值差在m之内的最长子串。
据他们说有O(n)的做法,不过我打了O(nlogn)的打法,跑进了1s,反正O(能过)就行。
我的nlogn是二分答案+单调队列。二分答案去验证,挨个移动,看是否满足条件。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define pos(i,a,b) for(int i=(a);i<=(b);i++) #define pos2(i,a,b) for(int i=(a);i>=(b);i--) int n,m; #define N 1001000 struct haha { int to,next,w; }; int read() { int x=0; char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x; } haha edge[N*4]; int head[N],cnt=1; void add(int u,int v,int w) { edge[cnt].w=w; edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt++; } struct qian { int fir,firch; int sec,secch; int roadfir,roadsec;int roadfirch,roadsecch; }cun[N]; int fa[N]; void dfs(int now) { for(int i=head[now];i;i=edge[i].next) { int to=edge[i].to; int w=edge[i].w; dfs(to); if(cun[now].sec<cun[to].fir+w) { cun[now].sec=cun[to].fir+w; cun[now].secch=to; if(cun[now].sec>cun[now].fir) { swap(cun[now].sec,cun[now].fir); swap(cun[now].secch,cun[now].firch); } } } } void dp(int now,int w) { if(now==1) { cun[now].roadfir=cun[now].fir; cun[now].roadsec=cun[now].sec; cun[now].roadfirch=cun[now].firch; cun[now].roadsecch=cun[now].secch; } else { if(cun[fa[now]].roadfirch!=now) { cun[now].roadfir=cun[fa[now]].roadfir+w; cun[now].roadfirch=fa[now]; cun[now].roadsec=cun[now].fir; } else { if(cun[now].fir>cun[fa[now]].roadsec+w) { cun[now].roadfir=cun[now].fir; cun[now].roadfirch=cun[now].firch; cun[now].roadsec=max(cun[now].sec,cun[fa[now]].roadsec+w); } else { cun[now].roadfir=cun[fa[now]].roadsec+w; cun[now].roadfirch=fa[now]; cun[now].roadsec=cun[now].fir; } } } for(int i=head[now];i;i=edge[i].next) { int to=edge[i].to; int ww=edge[i].w; dp(to,ww); } } int f[N]; int qmax[N],hed,tail; int qmin[N],beg,ed; bool find(int val){ hed=tail=0; beg=ed=0; for(int i=1;i<=n;i++){ while(hed<tail&&i-qmax[hed]>=val) hed++; while(beg<ed&&i-qmin[beg]>=val) beg++; while(hed<tail&&f[qmax[tail-1]]<f[i]) tail--;qmax[tail++]=i; while(beg<ed&&f[qmin[ed-1]]>f[i]) ed--;qmin[ed++]=i; if(i>=val&&f[qmax[hed]]-f[qmin[beg]]<=m) return true; } return false; } int main() { //freopen("race.in","r",stdin); //freopen("race.out","w",stdout); n=read();m=read(); pos(i,2,n) { int x,y; x=read();y=read(); add(x,i,y); fa[i]=x; } dfs(1); dp(1,0); for(int i=1;i<=n;i++) cout<<cun[i].roadfir<<" "<<cun[i].roadsec<<endl; while(1); for(int i=1;i<=n;i++) f[i]=cun[i].roadfir; int l=1,r=n+1; while(l<r-1){ int mid=l+r>>1; if(find(mid))l=mid; else r=mid; } int l=1,r=n+1; while(l<r-1) { int mid=(l+r)>>1; if(find(mid)) l=mid; else r=mid; } cout<<l; //while(1); return 0; }
[BZOJ 2500]幸福的道路 树形dp+单调队列+二分答案的更多相关文章
- (noip模拟二十一)【BZOJ2500】幸福的道路-树形DP+单调队列
Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图. ...
- bzoj2500幸福的道路 树形dp+单调队列
2500: 幸福的道路 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 434 Solved: 170[Submit][Status][Discuss ...
- 【bzoj2500】幸福的道路 树形dp+单调队列
Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图. ...
- 【bzoj2500】幸福的道路 树形dp+倍增RMQ+二分
原文地址:http://www.cnblogs.com/GXZlegend/p/6825389.html 题目描述 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一 ...
- [BZOJ 2500] 幸福的道路
照例先贴题面(汪汪汪) 2500: 幸福的道路 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 368 Solved: 145[Submit][Sta ...
- bzoj2500: 幸福的道路(树形dp+单调队列)
好题.. 先找出每个节点的树上最长路 由树形DP完成 节点x,设其最长路的子节点为y 对于y的最长路,有向上和向下两种情况: down:y向子节点的最长路g[y][0] up:x的次长路的g[x][1 ...
- ●BZOJ 2500 幸福的道路
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2500 题解: DFS,单调队列 首先有一个结论,距离树上某一个点最远的点一定是树的直径的一个 ...
- 【BZOJ2500】幸福的道路 树形DP+RMQ+双指针法
[BZOJ2500]幸福的道路 Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的 ...
- Codeforces 980F Cactus to Tree 仙人掌 Tarjan 树形dp 单调队列
原文链接https://www.cnblogs.com/zhouzhendong/p/CF980F.html 题目传送门 - CF980F 题意 给定一个 $n$ 个节点 $m$ 条长为 $1$ 的边 ...
随机推荐
- 4.如何实现用MTQQ通过服务器实现订阅者和发布者的通讯
1.本例子意在用moquette服务器来作为消息转发,通过订阅者订阅消息,发布者发布消息,然后发布者的消息可以通过服务器转发给订阅者 服务器例子: https://github.com/andsel/ ...
- pdf文件之itextpdf插入html内容以及中文解决方案
简述 目前网上已经有很多种html文件直接转pdf的技术帖子,但是很少有直接将部分html作为段落插入到pdf中,而且也没有一个可以很好的解决中文显示的问题. 因此今天上午围绕这个问题进行了研究,把解 ...
- Linux进阶命令-sort、uniq、 cut、sed、grep、find、awk
命令难度总体来说有简入难,参数都是工作中常常用到的.如果涉及到一些生僻的参数还请百度或man一下. sort(参考学习网站:http://www.cnblogs.com/dong008259/arch ...
- Button动态样式取代xml
还在为 textview以及button 的各种样式而烦恼的童鞋们请往这里看~~~~ 一次性解决 textview以及button的样式,再也不用写xml了!!! 全部动态预设置,拒绝堆代码,拒绝xm ...
- SpringMvc多视图配置(jsp、velocity、freemarker) velocity在springmvc.xml配置VelocityViewResolver,VelocityConfigurer,FreeMarkerConfigurer,FreeMarkerViewResolver
?xml version="1.0"encoding="UTF-8"?> <beans xmlns="http://www.springf ...
- 前端页面——Cookie与Session有什么区别
我们在实际生活中总会遇到这样的事情,我们一旦登录(首次输入用户名和密码)某个网站之后,当我们再次访问的时候(只要不关闭浏览器),无需再次登录.而当我们在这个网站浏览一段时间后,它会产生我们浏览的记录, ...
- icon button样式(类似windows桌面图标)
<Style x:Key="IconButton" TargetType="{x:Type Button}"> <Setter Propert ...
- Java面向对象之抽象类,接口
抽象类: 含有抽象方法的类被声明为抽象类 抽象方法由子类去实现 含有抽象方法的类必须被声明为抽象类 抽象类被子类继承,子类(如果不是抽象类)必须重写抽象类中的所有抽象方法 抽象方法: 声明而未被实现的 ...
- 在Visual Studio 2017中发现的问题
最近抽时间学习了一下 C# 6.0 的新特性,其中的一个新特性是 ?. 运算符,请看下面的一个简单示例: 当我故意修改成错误代码的时候,请接着看下面的示例: 我想把代码修改成list?[0].Coun ...
- Linux,activemq-cpp之消息过滤器
假设过滤器字符串如下: filt1=aaaa filt2=bbbb filt3=cccc activeMQ-cpp中消息过滤器,在发送消息的producer.cpp中,对message进行属性设置,m ...