2019百度之星 - 复赛 HDU-6725 Diversity 树形dp

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

题解:每个节点要么取l[i],要么取r[i],对于每个节点维护下取最小最大值时的结果即可

#include 
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
vector v[N];
ll dp[N][2];
int l[N], r[N];
void dfs(int u, int fa) {
    int flag = 0;
    ll cnt1 = 0, cnt2 = 0;
    int to;
    for(int i = 0; i < v[u].size(); i++) {
        to = v[u][i];
        if(to == fa) continue;
        dfs(to, u);
        cnt1 += max(dp[to][0] + abs(l[u] - l[to]), dp[to][1] + abs(l[u] - r[to]));
        cnt2 += max(dp[to][0] + abs(r[u] - l[to]), dp[to][1] + abs(r[u] - r[to]));
        flag = 1;
    }
    if(flag) {
        dp[u][0] = cnt1;
        dp[u][1] = cnt2;
    } else {
        dp[u][0] = 0;
        dp[u][1] = 0;
    }
}
int n;
int main() {
    int T;
    int x, y;
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) v[i].clear();
        for(int i = 1; i < n; i++) {
            scanf("%d %d", &x, &y);
            v[x].push_back(y);
            v[y].push_back(x);
        }
        for(int i = 1; i <= n; i++)
            scanf("%d %d", &l[i], &r[i]);
        dfs(1, 0);
        printf("%lld\n", max(dp[1][0], dp[1][1]));
    }
    return 0;
}

 

你可能感兴趣的:(树形dp)