专栏文章
CF2152H1 Victorious Coloring (Easy Version)
CF2152H1题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minmyk2z
- 此快照首次捕获于
- 2025/12/02 05:02 3 个月前
- 此快照最后确认于
- 2025/12/02 05:02 3 个月前
线性规划对偶秒了。
由于 ,考虑 解决单次询问。
首先显然红点形成一个连通块。可以写出线性规划(令 表示一个连通块):
对偶后有:
假设 是整数,那么问题相当于要选出若干个连通块,使得每个点最多被一个连通块包含,且每个选择的连通块 都有 的价值,要求最大化选出的连通块的价值。
考虑树形 DP。设 表示 是否被一个连通块包含, 子树内除了包含 的连通块的价值之和的最大值。
转移是简单的。考虑加入一个边权为 的儿子 :
- 若 都没有被连通块包含,则贡献为 ;
- 若 没有被包含, 被包含,贡献为 ;
- 若 被包含, 没有被包含,贡献为 ;
- 若 都被包含,贡献为 ,因为它们可以选择属于同一个连通块或属于不同的连通块。
时间复杂度 。
CPP// Problem: H1. Victorious Coloring (Easy Version)
// Contest: Codeforces - Squarepoint Challenge (Codeforces Round 1055, Div. 1 + Div. 2)
// URL: https://codeforces.com/contest/2152/problem/H1
// Memory Limit: 1024 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))
using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;
const int maxn = 250100;
ll n, m, q, f[maxn][2];
vector<pii> G[maxn];
void dfs(int u, int fa) {
f[u][0] = f[u][1] = 0;
for (pii p : G[u]) {
ll v = p.fst, d = p.scd;
if (v == fa) {
continue;
}
dfs(v, u);
f[u][0] += max(f[v][0], f[v][1] + m - d);
f[u][1] += max({f[v][0] - d, f[v][1], f[v][1] + m - d * 2});
}
}
void solve() {
scanf("%lld", &n);
for (int i = 1; i <= n; ++i) {
vector<pii>().swap(G[i]);
}
for (int i = 1, u, v, d; i < n; ++i) {
scanf("%d%d%d", &u, &v, &d);
G[u].pb(v, d);
G[v].pb(u, d);
}
scanf("%lld", &q);
while (q--) {
scanf("%lld", &m);
dfs(1, -1);
printf("%lld\n", max(f[1][0], f[1][1] + m));
}
}
int main() {
int T = 1;
scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...