2022 年杭电多校第七场 1007 Weighted Beautiful Tree
Posted TURNINING
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022 年杭电多校第七场 1007 Weighted Beautiful Tree相关的知识,希望对你有一定的参考价值。
思路:考虑dp。
d
p
[
u
]
[
0
/
1
]
dp[u][0/1]
dp[u][0/1]表示
u
u
u的点权作为父边的
m
i
n
/
m
a
x
min/max
min/max。考虑转移,我们需要枚举当前节点修改后的权值,显然这个权值只会是与
u
u
u相连的所有边的边权和修改前
u
u
u的点权中的一个。
我们只需要把子树按照边权排序,然后依次枚举点权,当与该点相连的子树的边权等于点权时需要特判取:
m
i
n
(
d
p
[
v
]
[
1
]
,
d
p
[
v
[
[
0
]
)
min(dp[v][1], dp[v[[0])
min(dp[v][1],dp[v[[0]), 不相等的部分按照状态转移即可,可以通过维护两个指针实现。实现的细节看具体代码。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, int> P;
const int MAXN = 1e5 + 10;
const ll INF = 1e17;
struct edge int to, we;;
vector<edge> g[MAXN];
int n;
int c[MAXN], wn[MAXN];
ll dp[MAXN][2], pre[MAXN], sum[MAXN];
bool cmp(int x, int y) return pre[x] < pre[y];
ll cal(int u, int val)
if(val <= wn[u])
return 1ll * c[u] * (wn[u] - val);
else
return 1ll * c[u] * (val - wn[u]);
void dfs(int u, int fa)
dp[u][1] = dp[u][0] = INF;
vector<int> vec, val;
for(auto e : g[u])
int v = e.to;
int we = e.we;
if(v == fa) continue;
pre[v] = we;
vec.push_back(v); val.push_back(we);
dfs(v, u);
val.push_back(wn[u]);
val.push_back(pre[u]);
sort(vec.begin(), vec.end(), cmp);
sort(val.begin(), val.end());
int l = 0, r = 0;
ll p = 0, s = 0;
for(int i = 0; i < vec.size(); i++)
sum[i+1] = sum[i] + min(dp[vec[i]][1], dp[vec[i]][0]);
s += dp[vec[i]][1];
for(int i = 0; i < val.size(); i++)
while(l < vec.size() && pre[vec[l]] < val[i])
p += dp[vec[l]][0];
l++;
while(r < vec.size() && pre[vec[r]] <= val[i])
s -= dp[vec[r]][1];
r++;
ll w = cal(u, val[i]);
ll c = p + s + sum[r] - sum[l] + w;
if(val[i] <= pre[u]) dp[u][0] = min(dp[u][0], c);
if(val[i] >= pre[u]) dp[u][1] = min(dp[u][1], c);
void solve()
scanf("%d", &n);
for(int i = 1; i <= n; i++)
g[i].clear();
for(int i = 1; i <= n; i++)
scanf("%d", &c[i]);
for(int i = 1; i <= n; i++)
scanf("%d", &wn[i]);
for(int i = 1; i < n; i++)
int u, v, we; scanf("%d %d %d", &u, &v, &we);
g[u].push_back(v, we);
g[v].push_back(u, we);
pre[1] = 0;
dfs(1, 0);
printf("%lld\\n", min(dp[1][0], dp[1][1]));
int main()
int t = 1; scanf("%d", &t);
while(t--)
solve();
return 0;
以上是关于2022 年杭电多校第七场 1007 Weighted Beautiful Tree的主要内容,如果未能解决你的问题,请参考以下文章
2022 年杭电多校第七场 1007 Weighted Beautiful Tree