A. Parsa's Humongous Tree
https://codeforces.com/problemset/problem/1528/A
题意:给一个树,树中每个节点有一个取值范围。现要对每个点在取值范围内选一个数值,然后求每条边的权值和最大是多少,边的权值是相邻的点取值后相减的绝对值。
思路:动态规划,每个节点维护两种状态:当前节点取最大值和取最小值,以当前节点为根的子树的最大权重。考虑当前根节点为u的树,不断从子树中选取两种情况的最优解来更新两种状态即可。
总结:为什么一定是两个端点的数值?假如考虑当前的节点u,如果相邻节点比u大的多,那u越小,答案更优,反之亦然。所以取值时,一定是取两个端点中的其中一个。
inline void solve() {
int n;
cin >> n;
vector<pair<int, int>> a(n);
for (auto& [x, y] : a) {
cin >> x >> y;
}
vector<vector<int>> al(n);
for (int i = 0; i < n - 1; ++i) {
int u, v;
cin >> u >> v;
u --;
v --;
al[u].push_back(v);
al[v].push_back(u);
}
vector<array<long long, 2>> dp(n, {0ll, 0ll});
auto dfs = [&](auto&& self, int u, int p) ->void {
for (const auto& v : al[u]) {
if (v == p) {
continue;
}
self(self, v, u);
dp[u][0] += max(dp[v][0] +abs(a[v].first - a[u].first),
dp[v][1] + abs(a[v].second - a[u].first));
dp[u][1] += max(dp[v][0] + abs(a[v].first -a[u].second),
dp[v][1] +abs(a[v].second - a[u].second));
}
};
dfs(dfs, 0, -1);
cout << max(dp[0][0], dp[0][1]) << '\n';
}

浙公网安备 33010602011771号