2019 年百度之星·程序设计大赛 - 复赛 Diversity (树形DP)

题目:https://vjudge.net/contest/325352#problem/A

题意:给你一棵树,每个点给一个区间,可以选区间里面任何一个数,然后问怎么安排得到最大边两点之间的差值和,求这个最大差值和

思路:首先可以想到每个点肯定是选择区间端点值,也就是说每个点实际上只有两个值可以选,但是我们安排当前值求出最大边差值不一定最优,这个时候我们可以设立一个数组dp[n][2],代表选当前点的L能得到的最大值和当前选R能得到的最大值,这样最后递归到根节点1就能求出最大值是多少

 

 

#include<bits/stdc++.h>
#define maxn 100005
#define mod 1000000007
using namespace std;
typedef long long ll;
struct sss{
    ll l,r;
}a[maxn];
int t,n; 
vector<int> mp[maxn];
ll dp[maxn][2];
void dfs(int x,int f){
    for(int i=0;i<mp[x].size();i++){
        int v=mp[x][i];
        if(v==f) continue;
        dfs(v,x);
        dp[x][0]+=max(abs(a[x].l-a[v].l)+dp[v][0],abs(a[x].l-a[v].r)+dp[v][1]);//所有子树的差值和
        dp[x][1]+=max(abs(a[x].r-a[v].l)+dp[v][0],abs(a[x].r-a[v].r)+dp[v][1]);
    } 
}
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            mp[i].clear();
        }
        memset(dp,0,sizeof(dp));
        int x,y;
        for(int i=0;i<n-1;i++){
            scanf("%d%d",&x,&y);
            mp[x].push_back(y);
            mp[y].push_back(x);    
        }    
        for(int i=1;i<=n;i++){
            scanf("%d%d",&a[i].l,&a[i].r);
        }
        dfs(1,-1);
        printf("%lld\n",max(dp[1][0],dp[1][1])); 
    }
} 

 

转载于:https://www.cnblogs.com/Lis-/p/11502379.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值