题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6725
题解:每个节点要么取l[i],要么取r[i],对于每个节点维护下取最小最大值时的结果即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
vector<int> 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;
}