Topic links: point I ah ╭ (╯ ^ ╰) ╮
Subject to the effect:
Unrooted tree, each point there are two points right
with
turn selected,
is selected from a point may be obtained
is selected from a point may be obtained
Election off point can not be selected
both want to get the value of the right to own more and more and the difference of another person
before the election, and asked the end result is the number
Problem-solving ideas:
Suppose root,
represents
selected
results
represents
I selected
results
because then a person is selected, the other will adversely affect the
Then start changing the root
to retain the front and rear two small values of the two values for each node of
each change only when changing root
and
information of two nodes
update to
change the root similar questions:HDU Multi third correction 1011 Squrirrel - + tree root DP transducer
Core: DP + tree root change
#include<bits/stdc++.h>
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
#define fi first
#define se second
using namespace std;
typedef long long ll;
using pii = pair <ll,int>;
const int maxn = 1e5 + 5;
int T, n, a[maxn];
vector <int> g[maxn];
map <pii, int> m0[maxn], m1[maxn];
ll dp[maxn][2], ans;
inline void add0(int u, ll val, int v){
m0[u][{val, v}]++;
if(m0[u].size() > 2) m0[u].erase(--m0[u].end());
}
inline void add1(int u, ll val, int v){
m1[u][{val, v}]++;
if(m1[u].size() > 2) m1[u].erase(m1[u].begin());
}
inline void get(int u){
if(!m0[u].size()) {
dp[u][0] = dp[u][1] = a[u];
return;
}
dp[u][0] = m0[u].begin()->fi.fi;
dp[u][1] = (--m1[u].end())->fi.fi;
}
inline void dfs1(int u, int fa){
m0[u].clear(), m1[u].clear();
for(auto v : g[u]){
if(v == fa) continue;
dfs1(v, u);
add0(u, dp[v][1] + a[u], v);
add1(u, dp[v][0] + a[u], v);
}
get(u);
}
inline void move(int rt, int son){
m0[rt].erase( {dp[son][1] + a[rt], son} );
m1[rt].erase( {dp[son][0] + a[rt], son} );
get(rt);
add0(son, dp[rt][1] + a[son], rt);
add1(son, dp[rt][0] + a[son], rt);
get(son);
}
inline void dfs2(int u, int fa){
ans = max(ans, dp[u][0]);
for(auto v : g[u]){
if(v == fa) continue;
move(u, v);
dfs2(v, u);
move(v, u);
}
}
int main() {
scanf("%d", &T);
while(T--){
ans = -4e18;
scanf("%d", &n);
for(int i=1; i<=n; i++) scanf("%d", a+i), g[i].clear();
for(int i=1, x; i<=n; i++) scanf("%d", &x), a[i] -= x;
for(int i=1, u, v; i<n; i++) {
scanf("%d%d", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs1(1, 0);
dfs2(1, 0);
printf("%lld\n", ans);
}
}