Multi-field correction eighth HDU 1006 Acesrc and Travel - DP + tree root change

Topic links: point I ah ╭ (╯ ^ ╰) ╮

Subject to the effect:

    Unrooted tree, each point there are two points right a i a_i with b i b_i
     Z h a n g Zhang a n d and L i u Liu turn selected, Z h a n g Zhang is selected from a point may be obtained a i a_i
     L i u Liu is selected from a point may be obtained b i b_i 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
     Z h a n g Zhang before the election, and asked the end result is the number

Problem-solving ideas:

    Suppose root, a [ i ] = a [ i ] b [ i ] a[i] = a[i] - b[i]
     d p [ u ] [ 0 ] dp[u][0] represents Z h a n g Zhang selected u in results d p [ u ] [ 1 ] dp[u][1] represents L i u Liu I selected u in results
     d p [ u ] [ 0 ] = m i n ( d p [ v ] [ 1 ] + a [ u ] ) dp[u][0] = min(dp[v][1] + a[u])
     d p [ u ] [ 1 ] = m a x ( d p [ v ] [ 0 ] + a [ u ] ) dp[u][1] = max(dp[v][0] + a[u])
    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 r t rt and s o n son 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);
	}
}
Published 221 original articles · won praise 220 · views 20000 +

Guess you like

Origin blog.csdn.net/Scar_Halo/article/details/103180842