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 >&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 > eg(n + 1 , vct(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 l(n + 1 , 0) ;
	vct r(n + 1 , 0) ;
	vct > dp(n + 1 , vct (2 , 0)) ;
	
	vct > eg(n + 1 , vct(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 inq(n + 1 , 0) ;
	vct vis(n + 1 , 0) ;
	queue q ;
	vct 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