其他分享
首页 > 其他分享> > A. Parsa's Humongous Tree_基础树形dp

A. Parsa's Humongous Tree_基础树形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