ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

A. Parsa's Humongous Tree_基础树形dp

2022-05-12 00:01:38  阅读:169  来源: 互联网

标签:nxt Humongous int eg Tree Parsa vct now dp


A. Parsa's Humongous Tree_基础树形dp

题目大意

每一个点可以选择[li,ri]中任意整数作为权值,一条边的权值是两点权值之差的绝对值。问整棵树的权值和最大是多少。

思路和代码

哎,当时转移方程我都写好了,脑袋没转过弯来。

首先,做几个样例可以得出每个点的权值必取最大或者最小。

我当时去做了一个叶子节点向树内部的BFS,有点笨。这不就是dfs的回溯路径嘛...

所以简单做一个树形dp即可。

状态定义:dp[i,1/0]表示以i为根并且点i选择ri或者li时候的子树的最大值

转移方程具体见代码

int n , m , k ; 

int l[N] , r[N] ;

ll dp[N][2] ;

void dfs(int now , int pre , vct<vct<int> >&eg){
	
	for(int nxt : eg[now]){
		if(nxt == pre) continue ;
		dfs(nxt , now , eg) ;
		dp[now][1] += max(dp[nxt][0] + abs(r[now] - l[nxt]) , dp[nxt][1] + abs(r[now] - r[nxt])) ;
		dp[now][0] += max(dp[nxt][0] + abs(l[now] - l[nxt]) , dp[nxt][1] + abs(l[now] - r[nxt])) ;
	}
	
}

void solve(){
	cin >> n ;
	
	vct<vct<int> > eg(n + 1 , vct<int>(0)) ;
	
	rep(i , 1 , n)
		dp[i][0] = dp[i][1] = 0 ;
	
	rep(i , 1 , n) cin >> l[i] >> r[i] ;
	
	rep(i , 2 , n){
		int u , v ;
		cin >> u >> v ;
		eg[u].pb(v) ;
		eg[v].pb(u) ;
	}
	
	dfs(1 , -1 , eg) ;
	
	cout << max(dp[1][0] , dp[1][1]) << "\n" ;

	 
}//code_by_tyrii 

小结

简单树形dp,注意是在回溯的时候做dp转移(这好像是废话)

笑话

附上我的呆瓜bfs代码

void solve(){//错误代码!!
	int n ;
	cin >> n ;
	
	vct<ll> l(n + 1 , 0) ;
	vct<ll> r(n + 1 , 0) ;
	vct<vct<ll> > dp(n + 1 , vct<ll> (2 , 0)) ;
	
	vct<vct<int> > eg(n + 1 , vct<int>(0)) ;
	
	rep(i , 1 , n)
		dp[i][0] = dp[i][1] = 0 ;
	
	rep(i , 1 , n) cin >> l[i] >> r[i] ;
	
	rep(i , 2 , n){
		int u , v ;
		cin >> u >> v ;
		eg[u].pb(v) ;
		eg[v].pb(u) ;
	}
		
	vct<bool> inq(n + 1 , 0) ;
	vct<bool> vis(n + 1 , 0) ;
	queue<int> q ;
	vct<int> lf ;
	
	rep(i , 1 , n)
	if(eg[i].size() == 1)
	lf.pb(i) ;
	int rt = lf[0] ;
	for(int i = 1 ; i < lf.size() ; i ++ ) q.push(lf[i]) ;
	for(int i = 1 ; i < lf.size() ; i ++ ) inq[lf[i]] = 1 ;
	
	while(q.size()){
		int now = q.front() ;
		q.pop() ;
		vis[now] = 1 ;
		for(int nxt : eg[now]){
			
			if(vis[nxt]) continue ;
			//now 1 , nxt 0
			//now 0 , nxt 0
			ll tmp1 = max(dp[now][1] + abs(r[now] - l[nxt]) , dp[now][0] + abs(l[now] - l[nxt])) ;
			//now 1 , nxt 1
			//now 0 , nxt 1 
			ll tmp2 = max(dp[now][1] + abs(r[now] - r[nxt]) , dp[now][0] + abs(l[now] - r[nxt])) ;

			dp[nxt][0] += tmp1 ;
			dp[nxt][1] += tmp2 ;
			
			if(nxt != rt && !inq[nxt]){
				inq[nxt] = 1 ;
				q.push(nxt) ;
			}
		}
		
	}
	
	cout << max(dp[rt][0] , dp[rt][1]) << "\n" ; 
	 
}//code_by_tyrii 

bfs是可以做的!但是我懒得调了,有空再说8

标签:nxt,Humongous,int,eg,Tree,Parsa,vct,now,dp
来源: https://www.cnblogs.com/tyriis/p/16260543.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有