hdu6725(树形dp,区间选值,点权差最大)

题:http://acm.hdu.edu.cn/showproblem.php?pid=6725

分析:给节点选值肯定是选边界值。假设由节点是选中间值,那么肯定有比它选值更好的值,所以把选的可能定为2个。

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define MP make_pair
typedef long long ll;
typedef unsigned long long ull;
const int mod=998244353;
const int inf=0x3f3f3f3f;
const int M=1e5+5;
ll l[M],r[M];
ll dp[M][2];
vector<int>g[M];
void dfs(int  u,int fa){
    for(auto v:g[u]){
        if(v!=fa){
            dfs(v,u);
            dp[u][0]+=max(dp[v][0]+abs(l[v]-l[u]),dp[v][1]+abs(r[v]-l[u]));
            dp[u][1]+=max(dp[v][0]+abs(l[v]-r[u]),dp[v][1]+abs(r[v]-r[u]));
        }

    }

}
int main(){

    int t;
    scanf("%d",&t);
    while(t--){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            dp[i][0]=dp[i][1]=0,g[i].clear();
        for(int u,v,i=1;i<n;i++){
            scanf("%d%d",&u,&v);
            g[u].pb(v);
            g[v].pb(u);
        }
        for(int i=1;i<=n;i++)
            scanf("%lld%lld",&l[i],&r[i]);
        dfs(1,0);
        printf("%lld
",max(dp[1][0],dp[1][1]));
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/starve/p/13341241.html