[ABC259F] Select Edges 题解
Solution
考虑树形
我们可以注意到节点
但是此处没有给定
既然考虑一个点与子节点之间边的情况不行,那么是否可以反过来想,考虑当前点是否与父节点相连的情况,此时每一个点只有与父节点的边选与不选两种情况。
现在我们重新定义状态,设
但是在求解的过程中我们需要保证每个节点
我们可以发现不选与子节点的边一定是一种情况,我们首先可以定义一个变量
此时如果我们选择其中一个节点与其的连边,那么这时答案的增量记为
此时我们选出的就是最大的几个正数,由于不超过
对于
特殊的,如果
若我们假定这棵树的根节点为
Code
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#define int long long
#define inl inline
using namespace std;
const int N = 3e5, INF = 1e9;
int n;
int d[N + 5];
int dp[N + 5][2];
struct Edge {
int v, w;
Edge () {}
Edge (int vv, int ww) : v(vv), w(ww) {}
};
vector<Edge> G[N + 5];
inl bool cmp(int x, int y) { return x > y; }
inl void dfs(int u, int fa) {
int sum = 0;
vector<int> stk;
for (auto it : G[u]) {
int v = it.v, w = it.w;
if (v == fa)
continue;
dfs(v, u), sum += dp[v][0];
stk.push_back(dp[v][1] - dp[v][0] + w);
}
sort(stk.begin(), stk.end(), cmp);
for (int i = 0; i < min((int)stk.size(), d[u] - 1); i++)
sum += max(0ll, stk[i]);
dp[u][0] = sum + ((d[u] && stk.size() > d[u] - 1) ? max(0ll, stk[d[u] - 1]) : 0);
dp[u][1] = !d[u] ? -INF : sum;
}
signed main() {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> d[i];
for (int i = 1, u, v, w; i < n; i++) {
cin >> u >> v >> w;
G[u].push_back(Edge(v, w)), G[v].push_back(Edge(u, w));
}
dfs(1, 0);
cout << max(dp[1][0], dp[1][1]);
return 0;
}
本文来自博客园,作者:zhou_ziyi,转载请注明原文链接:https://www.cnblogs.com/zhouziyi/p/17501221.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具