BZOJ 2500 幸福的道路 树形DP+单调队列

题目大意:给定一棵树,令a[i]为从第i个节点出发的最长链,求a[i]中最长的区间,满足区间内最大值与最小值之差不超过m

读错题害死人,脑残害死人

求a[i]显然是树形DP

考虑从一个点出发的链可以从子节点走,也可以从父节点走

因此我们DP两次,第一次求出从子节点走的最长链,第二次求出从父节点走的最长链,两次取max就是答案

但是直接DP会有问题,因为从父节点走的最长链可能是从自己的子树出发的,这样就会走重

因此除记录从子节点出发的最长链外还要记录一个从另一个子节点出发的次长链,如果最长链长度相同就从次长链走即可

第二问用单调队列随便搞搞就好了

时间复杂度O(n)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 1001001
using namespace std;
struct abcd{
	int to,f,next;
}table[M<<1];
int head[M],tot;
int n,m,ans;
long long f[M],g[M],h[M],a[M];
//f表示从子节点过来的最长链
//g表示从子节点过来的次长链
//h表示从父节点过来的最长链
void Add(int x,int y,int z)
{
	table[++tot].to=y;
	table[tot].f=z;
	table[tot].next=head[x];
	head[x]=tot;
}
void Tree_DP1(int x)
{
	int i;
	for(i=head[x];i;i=table[i].next)
	{
		Tree_DP1(table[i].to);
		if(f[table[i].to]+table[i].f>f[x])
			g[x]=f[x],f[x]=f[table[i].to]+table[i].f;
		else if(f[table[i].to]+table[i].f>g[x])
			g[x]=f[table[i].to]+table[i].f;
	}
}
void Tree_DP2(int x)
{
	int i;
	a[x]=max(f[x],h[x]);
	for(i=head[x];i;i=table[i].next)
	{
		long long temp=( f[x]==f[table[i].to]+table[i].f ? g[x] : f[x] );
		temp=max(temp,h[x]);
		h[table[i].to]=temp+table[i].f;
		Tree_DP2(table[i].to);
	}
}
void Monotonous_Queue()
{
	static int q_max[M],r_max,h_max;
	static int q_min[M],r_min,h_min;
	int i,j;
	for(j=0,i=1;i<=n;i++)
	{
		{
			int *q=q_max,&r=r_max,&h=h_max;
			while( r-h>=1 && a[i]>=a[q[r]] )
				q[r--]=0;
			q[++r]=i;
		}

		{
			int *q=q_min,&r=r_min,&h=h_min;
			while( r-h>=1 && a[i]<=a[q[r]] )
				q[r--]=0;
			q[++r]=i;
		}

		while(a[q_max[h_max+1]]-a[q_min[h_min+1]]>m)
		{
			++j;
			if(q_min[h_min+1]==j)
				q_min[++h_min]=0;
			if(q_max[h_max+1]==j)
				q_max[++h_max]=0;
		}

		ans=max(ans,i-j);
	}
}
int main()
{
	int i,x,y;
	cin>>n>>m;
	for(i=2;i<=n;i++)
	{
		scanf("%d%d",&x,&y);
		Add(x,i,y);
	}
	Tree_DP1(1);
	Tree_DP2(1);
	Monotonous_Queue();
	cout<<ans<<endl;
}
时间: 2024-08-25 10:43:59

BZOJ 2500 幸福的道路 树形DP+单调队列的相关文章

bzoj2500幸福的道路 树形dp+单调队列

2500: 幸福的道路 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 434  Solved: 170[Submit][Status][Discuss] Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图. 他们不愿枯燥的每天从同一个地方开始他们的锻炼,所以他们准备给起点标号后顺序地从每个起点开始(第

BZOJ 2500 幸福的道路

题面: 2500: 幸福的道路 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 366  Solved: 144[Submit][Status][Discuss] Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图. 他们不愿枯燥的每天从同一个地方开始他们的锻炼,所以他们准备给起点标号后顺序地从每个起点

bzoj2500: 幸福的道路(树形dp+单调队列)

好题.. 先找出每个节点的树上最长路 由树形DP完成 节点x,设其最长路的子节点为y 对于y的最长路,有向上和向下两种情况: down:y向子节点的最长路g[y][0] up:x的次长路的g[x][1]+dis[x][y] up:up[fa[x]]+dis[x][y] dfs1找向下,即向子节点的最长路 dfs2找向上的最长路 最后最长路f[i]=max(up[x],g[x][0]) 第二部分 找最长连续子序列,使得序列中abs(mx-mn)<=m 这次学习了用单调队列的做法 两个队列mx,mn

【BZOJ2500】幸福的道路 树形DP+RMQ+双指针法

[BZOJ2500]幸福的道路 Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图. 他们不愿枯燥的每天从同一个地方开始他们的锻炼,所以他们准备给起点标号后顺序地从每个起点开始(第一天从起点一开始,第二天从起点二开始……). 而且他们给每条道路定上一个幸福的值.很显然他们每次出发都想走幸福值和最长的路线(即从起点到树上的某一点路径中最长的一条). 他

POJ - 3162 Walking Race 树形dp 单调队列

POJ - 3162Walking Race 题目大意:有n个训练点,第i天就选择第i个训练点为起点跑到最远距离的点,然后连续的几天里如果最远距离的最大值和最小值的差距不超过m就可以作为观测区间,问这样的区间最长的长度? 一开始楞是没看懂题意,最讨厌这种四级题,这是在刁难我英语小能手(能用翻译的就不自己动手).而且这题感觉单调队列那里的处理更难一点,不过还是来说一说怎么树形dp取得最远距离,先画个简简单单丑丑的图 我们直接从1作为根节点开始dfs的话,可以处理1的最远距离,并且可以得出到其它节点

BZOJ 2500 幸福的道路(race) 树上直径+平衡树

structHeal { priority_queue<int> real; priority_queue<int> stack; voidpush(int x) { real.push(x); } voidpop(int x) { stack.push(x); } inttop() { while(real.empty()==0&&stack.empty()==0&&real.top()==stack.top()) real.pop(),stack

hdu 4123 树形DP+单调队列

http://acm.hust.edu.cn/vjudge/problem/25790 这题基本同poj 3162 要注意mx,mx2,vx,vx2每次都要初始化 #include <iostream> #include <string> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <algorithm>

BZOJ 2878([Noi2012]迷失游乐园-树形DP+环加外向树+期望DP+vector的erase)

2878: [Noi2012]迷失游乐园 Time Limit: 10 Sec  Memory Limit: 512 MBSec  Special Judge Submit: 319  Solved: 223 [Submit][Status] Description 放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩.进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐园抽象成有n个景点.m条道路的无向连通图,且该图中至多有一个环(即m只可能等于n或者n-1).小Z现在所在的大门也正好是

[BZOJ 4033] [HAOI2015] T1 【树形DP】

题目链接:BZOJ - 4033 题目分析 使用树形DP,用 f[i][j] 表示在以 i 为根的子树,有 j 个黑点的最大权值. 这个权值指的是,这个子树内部的点对间距离的贡献,以及 i 和 Father[i] 之间的边对答案的贡献(比如这条边对黑点对距离和的贡献就是子树内部的黑点数 * 子树外部的黑点数 * 这条边的权值). 然后DFS来求,枚举 i 的每个儿子 j,现在的 f[i][] 是包含了 [1, j-1] 子树,然后两重循环枚举范围是 [1, j - 1] 的子树总 Size 和