【Codeforces】CF 2014 F

Sheriff’s Defense

#树形结构 #树形dp #动态规划

题目描述

The folk hero Robin Hood has been troubling Sheriff of Nottingham greatly. Sheriff knows that Robin Hood is about to attack his camps and he wants to be prepared.

Sheriff of Nottingham built the camps with strategy in mind and thus there are exactly n n n camps numbered from 1 1 1 to n n n and n − 1 n-1 n1 trails, each connecting two camps. Any camp can be reached from any other camp. Each camp i i i has initially a i a_i ai gold.

As it is now, all camps would be destroyed by Robin. Sheriff can strengthen a camp by subtracting exactly c c c gold from each of its neighboring camps and use it to build better defenses for that camp. Strengthening a camp doesn’t change its gold, only its neighbors’ gold. A camp can have negative gold.

After Robin Hood’s attack, all camps that have been strengthened survive the attack, all others are destroyed.

What’s the maximum gold Sheriff can keep in his surviving camps after Robin Hood’s attack if he strengthens his camps optimally?

Camp a a a is neighboring camp b b b if and only if there exists a trail connecting a a a and b b b. Only strengthened camps count towards the answer, as others are destroyed.

输入格式

The first line contains a single integer t t t ( 1 ≤ t ≤ 1 0 4 1 \le t \le 10^4 1t104) — the number of test cases.

Each test case begins with two integers n n n, c c c ( 1 ≤ n ≤ 2 ⋅ 1 0 5 , 1 ≤ c ≤ 1 0 9 1 \le n \le 2\cdot10^5, 1 \le c \le 10^9 1n2105,1c109) — the number of camps and the gold taken from each neighboring camp for strengthening.

The second line of each test case contains n n n integers a 1 , a 2 , … , a n a_1,a_2,\dots,a_n a1,a2,,an ( − 1 0 9 ≤ a i ≤ 1 0 9 -10^9 \le a_i \le 10^9 109ai109) — the initial gold of each camp.

Then follow n − 1 n-1 n1 lines, each with integers u u u, v v v ( 1 ≤ u , v ≤ n 1 \le u, v \le n 1u,vn, u ≠ v u \ne v u=v) — meaning that there is a trail between u u u and v v v.

The sum of n n n over all test cases doesn’t exceed 2 ⋅ 1 0 5 2\cdot10^5 2105.

It is guaranteed that any camp is reachable from any other camp.

输出格式

Output a single integer, the maximum gold Sheriff of Nottingham can keep in his surviving camps after Robin Hood’s attack.

样例 #1

样例输入 #1

5
3 1
2 3 1
1 2
2 3
3 1
3 6 3
1 2
2 3
3 1
-2 -3 -1
1 2
2 3
6 1
5 -4 3 6 7 3
4 1
5 1
3 5
3 6
1 2
8 1
3 5 2 7 8 5 -3 -4
7 3
1 8
4 3
3 5
7 6
8 7
2 1


样例输出 #1

3
8
0
17
26

解题思路

看这种具有依赖关系的树形结构,很容易就想到树形 d p dp dp,显然这题也是

我们设计两个状态 f u , 0 f_{u,0} fu,0 f u , 1 f_{u,1} fu,1,分别表示当前 u u u节点不选择强化和 u u u节点选择强化的最大贡献。

选择强化当前节点就要使相邻的节点减去 c c c这个贡献,包括其父节点,不过对于父节点的贡献可以等递归回溯到父节点累加为 2 ∗ c 2*c 2c,因此转移方程如下:

{ f u , 0 + = max ⁡ ( f v , 0 , f v , 1 ) f u , 1 + = max ⁡ ( f v , 0 , f v , 1 − 2 ∗ c ) \begin{cases} f_{u,0} += \max(f_{v,0},f_{v,1}) \\ f_{u,1} += \max(f_{v,0},f_{v,1} - 2*c) \end{cases} {fu,0+=max(fv,0,fv,1)fu,1+=max(fv,0,fv,12c)

代码

 
const int N = 2e5 + 10;
 
void solve() {
	int n, c;
	std::cin >> n >> c;
 
	std::vector<int>w(n + 1);
	for (int i = 1; i <= n; ++i) {
		std::cin >> w[i];
	}
 
	std::vector<std::vector<int>>e(n + 1);
	for (int i = 1; i <= n - 1; ++i) {
		int u, v;
		std::cin >> u >> v;
		e[v].emplace_back(u);
		e[u].emplace_back(v);
	}
 
 
	std::vector <std::array<int, 2>> f(n + 1);
	auto dfs = [&](auto&& self, int u, int fa)->void {
		f[u][0] = 0; f[u][1] = w[u];
 
		for (auto& v : e[u]) {
			if (v == fa) continue;
			self(self, v, u);
 
			f[u][0] += std::max(f[v][0], f[v][1]);
			f[u][1] += std::max(f[v][0], f[v][1] - 2 * c);
		}
		};
 
	dfs(dfs, 1, -1);
 
	int res = std::max(f[1][0], f[1][1]);
 
	std::cout << res << "\n";
}
 
signed main() {
	std::ios::sync_with_stdio(0);
	std::cin.tie(0);
	std::cout.tie(0);
 
	int t = 1;
	std::cin >> t;
 
	while (t--) {
		solve();
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值