`
darren_nizna
  • 浏览: 72615 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

[PKU/POJ][3162][Walking Race][线段树+树形DP]

 
阅读更多

1.给你一棵边带权的树,求出树中每一个点到其它点的最大距离。

2.在一个整数序列中找一个最大的连续序列,使得该序列中最大数和最小数之差不超过 m 。

问题 1 可用树形 DP 解决。对树进行 DFS,DFS 过程中,对根 R,记录他的孩子结点到他是最大距离和次大距离以及相应的结点。然后用一次 BFS 更新。

问题 2 用两个指针 head, tail分别指向连续序列的首尾,如果区间 [head,tail] 满足条件,则 tail++,更新值最大最小值,不满足条件则 head++, 用线段树更新最大最小值。

 

注意图不能用 STL 的 vector 和 pair 保存,这样会 TLE。

 

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int const N= 1000010, inf= 0x7fffffff;
int dp[N][2], pos[N][2], flag[N], que[N];
int n, m, cnt;

#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))

struct Edge{
	int adj, wt;
	Edge* next;
}EG[N<<1];

Edge* mat[N];

struct TB{
	int Min, Max;
}tb[N<<2];

inline void add( int u, int v, int d ){
	++cnt;
	EG[cnt].adj= v; EG[cnt].wt= d; 
	EG[cnt].next= mat[u]; mat[u]= EG+ cnt;
	
	cnt++;
	EG[cnt].adj= u; EG[cnt].wt= d;
	EG[cnt].next= mat[v]; mat[v]= EG+ cnt;
}

int dfs( int u ){
	dp[u][0]= 0; dp[u][1]= 0; flag[u]= 1;
	
	for( Edge* p= mat[u]; p; p= p->next )
	if( !flag[p->adj] ){
		int v= p->adj, w= p->wt;
		
		int tmp= w+ dfs( v );
		
		if( tmp> dp[u][0] ){
			dp[u][1]= dp[u][0]; pos[u][1]= pos[u][0];
			dp[u][0]= tmp; pos[u][0]= v;
		}
		else if( tmp> dp[u][1] ){
			dp[u][1]= tmp; pos[u][1]= v;
		}
	}
	return dp[u][0];
}

void bfs( int rt ){
	for( int i= 0; i<= n; ++i ) flag[i]= 0;
	int head= 0, tail= 0; que[0]= rt; flag[rt]= 1;
	
	while( head<= tail ){
		int u= que[head++];
		
		for( Edge* p= mat[u]; p; p= p->next )
		if( !flag[p->adj] ){
			int v= p->adj, w= p->wt;
			flag[v]= 1; que[++tail]= v;
			
			if( pos[u][0]== v ) w+= dp[u][1];
			else w+= dp[u][0];
			
			if( w> dp[v][0] ){
				dp[v][1]= dp[v][0]; pos[v][1]= pos[v][0];
				dp[v][0]= w; pos[v][0]= u;
			}
			else if( w> dp[v][1] ){
				dp[v][1]= w; pos[v][1]= u;
			}
		}
	}
}

void build( int L, int R, int rt ){
	if( L== R ){
		tb[rt].Max= tb[rt].Min= dp[L][0]; return; }
	
	int mid= (L+ R)>> 1;
	build( L, mid, rt<<1 ); 
	build( mid+ 1, R, rt<<1|1 );
	
	tb[rt].Max= max( tb[rt<<1].Max, tb[rt<<1|1].Max );
	tb[rt].Min= min( tb[rt<<1].Min, tb[rt<<1|1].Min );
} 

int ansMin, ansMax;
void query( int x, int y, int L, int R, int rt ){
	if( L== x && y== R || L== R ){
		ansMin= min( ansMin, tb[rt].Min );
		ansMax= max( ansMax, tb[rt].Max );
		return;
	}
	
	int mid= (L+ R)>>1;
	if( y<= mid ) query( x, y, L, mid, rt<<1 );
	else if( x> mid ) query( x, y, mid+ 1, R, rt<<1|1 );
	else{
		query( x, mid, L, mid, rt<<1 );
		query( mid+ 1, y, mid+ 1, R, rt<<1|1 );
	}
}

int main(){
	scanf("%d%d",&n,&m ); cnt= -1;
	for( int i= 0; i<= n; ++i ){
		mat[i]= 0; flag[i]= 0;
	}
	
	for( int i= 2; i<= n; ++i ){
		int x, y;
		scanf("%d%d",&x,&y);
		add( i, x, y );
	}
	
	dfs(1);  bfs(1);  build(1,n,1);
	
	int head= 1, tail= 1, ans= 1;
	ansMax= dp[1][0], ansMin= dp[1][0];
	while( head<= tail && tail<= n ){
		if( ansMax- ansMin<= m ){
			ans= max( ans, tail- head+ 1 );
			
			tail++;
			ansMax= max( ansMax, dp[tail][0] );
			ansMin= min( ansMin, dp[tail][0] );
		}
		else{
			++head;
			ansMin= inf, ansMax= -inf;
			query( head, tail, 1, n, 1 );
		}
		
		if( n- head+ 1< ans ) break;
	}
	printf("%d\n", ans );

	return 0;
}
 
1
1
分享到:
评论

相关推荐

    PKU_poj 1197

    ACM PKU_poj 1197 仓库问题源代码,愿与大家共享。若谁更好的代码,多谢提供。

    PKU 、POJ ACM/ICPC300多题的代码

    标题“PKU 、POJ ACM/ICPC300多题的代码”指的是北京大学(PKU)和编程在线评测平台POJ上收集的300多道ACM/ICPC(国际大学生程序设计竞赛)比赛题目解题代码。这个压缩包包含了解决这些竞赛问题的算法和程序实现,是...

    pku2104.rar_线段树

    PKU2104是北京大学的一道算法题目,其提供的源代码着重展示了线段树在“找数据”问题中的应用。 线段树的基本思想是将一个区间分解为若干个子区间,然后对每个子区间构建一棵小树,这些小树通过节点连接形成一个...

    pku1151.rar_Atlantis_pku 11_poj Atlant_poj Atlantis_poj11

    标题中的“pku1151.rar_Atlantis_pku 11_poj Atlant_poj Atlantis_poj11”似乎是指北京大学(Peking University, PKU)编程竞赛中的一道题目,编号为1151,与“Atlantis”这个主题相关。这道题目在多个平台上也被提及...

    线段树六题

    线段树是一种非常有效的数据结构,主要用于解决区间查询和更新的问题,常用于算法竞赛和实际应用中的问题求解。接下来,我们将详细探讨“线段树六题”中各个题目的相关知识点。 ### 1. PKU2352 star2 校门外的树 **...

    PKU_poj 1001~1009

    标题“PKU_poj 1001~1009”揭示了这是一组与北京大学(Peking University)编程竞赛平台POJ相关的解决方案。在这个压缩包中,包含了从问题1001到1009的C++源代码,表明这些代码已经过验证并成功解决了对应的算法问题。...

    POJ动态规划题目全面总结

    PKU Online Judge上面很全面的动态规划试题总结。动态规划是ACM考点中最重要的一大类算法之一,对于工作人员来说,动态规划也是实际开发中...这是POJ上面很多DP题目的总结与深刻分析。利于算法学习,学长给的,在此分享

    pku(poj)--2494--Acid Text--java代码

    - **技能提升**:项目涉及的数据结构(如二维数组、树形图、向量等)和算法(如字符串处理、文件读写)对于提高编程技能非常有帮助。 - **创新思维**:在解决具体问题时,鼓励学生思考不同的解决方案,培养创新思维...

    pku_poj_2187.rar_poj 2187_凸包问题

    标题中的“pku_poj_2187.rar_poj 2187_凸包问题”表明这是一个关于北京大学(Peking University, PKU)编程竞赛平台POJ上的第2187题,题目主要涉及凸包问题。描述中的“O(nlogn)凸包问题 poj2187”提示我们解决这个...

    POJ PKU 必做题+部分难题1001-2500

    1011,1012,1013,1014,1015,1017,1026,1028,1032,1035,1041,1046,1129 1149 1154 1165 1182 1185 1190 1191 1201 1251 1273 1275 1276 1286 1322 1338 1363 1364 1401 1456 1459 1564 1579 1637 1657 1658 ...

    pku1088.rar_pku 10_pku 1088_poj 1088

    标题中的“pku1088.rar_pku 10_pku 1088_poj 1088”指的是北京大学(Peking University, PKU)编程竞赛中的第1088题,也称为POJ(Peking University Online Judge)的1088题。这个题目在编程竞赛社区中通常有一个特定的...

    树形dp问题总结(转发)

    树形动态规划(Tree DP)是一种在树结构上进行优化计算的方法,主要应用于解决与树相关的最优化问题。本文将围绕“树形DP问题总结”展开,以“二叉苹果树(ural 1108)”为例,探讨树形DP的思路和应用。 在“二叉...

    POJ 部分题解 解题报告

    10. **POJ 2528 线段树.txt**:这是第三个线段树相关的题目,解题报告可能会深入讲解线段树在不同场景下的应用。 通过阅读这些解题报告,你可以学习到各种高级算法的应用,如动态规划、搜索算法、数据结构(如线段...

    poj3252.rar_pku 3252_poj32

    标题中的"poj3252.rar_pku 3252_poj32"表明这是一个与编程竞赛相关的资源,具体来说是北京大学(PKU)ACM竞赛中的问题3252。"poj"通常指的是"Programming Online Judge",这是一个在线编程比赛平台,而"Pku"则代表...

    poj 130题 acm pku

    【标题】"poj 130题 acm pku" 涉及的是ACM(国际大学生程序设计竞赛)中的PKU(北京大学)在线判题系统POJ(Problem Online Judge)的相关题目。ACM/ICPC(International Collegiate Programming Contest)是全球...

    北大POJ初级-所有题目AC代码+解题报告

    北京大学(Peking University, 简称PKU)的POJ(Peking University Online Judge)是一个为计算机科学爱好者和学生提供在线编程训练的平台。这个资源集合了北大POJ初级阶段的所有题目,包含已通过(Accepted, AC)的...

    poj(PKU-2314-POJ language

    根据提供的文件信息,我们可以分析出该段代码是用于解决POJ平台上的2314题的一种解决方案,主要涉及到了变量管理、表达式处理等方面。下面将详细解释代码中的关键概念和实现逻辑。 ### 关键概念解析 #### Variable...

    程序设计与算法一OpenJudge题解-ACM资源

    C http://www.icourse163.org/learn/PKU-1001553023 CC++CC++ http://cxsjsxmooc.openjudge.cn/2017t1summerall/

Global site tag (gtag.js) - Google Analytics