Acesrc and Travel 换根

link

To change the root DP, it is recommended to use the following writing method, by storing the prefix extremum, so that there is no need for complicated classification discussions


#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define rep(i,a,b) for(ll i=(a);i<=(b);i++)
#define per(i,a,b) for(ll i=(a);i>=(b);i--)
using namespace std;
typedef long long ll;
typedef vector<int> VI;
typedef pair<int,int> pii;
const ll  inf  = 1ll<<60;
const int mod  = 1e9  + 7;
const int maxn = 1e6  + 4;
const int N    = 1000 + 5;
ll qpow(ll x,ll y){
    
    ll ans=1;x%=mod;assert(y>=0);while(y){
    
     if(y&1) ans=ans*x%mod; x=x*x%mod; y>>=1;}return ans;}
//ctrl + h 查询 替换	ctrl + shift + t 恢复刚刚关闭的标签
//ctrl + shift + d/k 复制/删除当前行 
//alt  + shift + 1/2/3/4 分屏
struct node {
    
    ll x,y;};
int _,n;
VI G[maxn];
vector<node>kk[maxn];
ll a[maxn],b[maxn],dp[maxn][2],ans;
void dfs(int u,int fa) {
    
    	
	dp[u][0]=inf;dp[u][1]=-inf;
	for(int v:G[u]) if(v!=fa) {
    
    
		dfs(v,u);
		dp[u][0]=min(dp[u][0],dp[v][1]);
		dp[u][1]=max(dp[u][1],dp[v][0]);
	}
	if(dp[u][0]==inf) dp[u][1]=dp[u][0]=0;
	dp[u][1]+=a[u];dp[u][0]+=a[u];
}
void dfs1(int u,int fa) {
    
      
	dp[u][0]=inf;dp[u][1]=-inf;
	for(int v:G[u]) {
    
    
		dp[u][0]=min(dp[u][0],dp[v][1]);
		dp[u][1]=max(dp[u][1],dp[v][0]);
		kk[u].pb({
    
    dp[u][0],dp[u][1]});
	}
	dp[u][0]+=a[u];dp[u][1]+=a[u];


	ans=max(ans,dp[u][0]);
	ll t0=inf,t1=-inf;
	for(int i=SZ(G[u])-1;i>=0;i--) {
    
    
		dp[u][0]=t0;dp[u][1]=t1;
		if(i) {
    
    
			dp[u][0]=min(kk[u][i-1].x,dp[u][0]);
			dp[u][1]=max(kk[u][i-1].y,dp[u][1]);
		}
		if(dp[u][0]==inf) dp[u][0]=dp[u][1]=0;
		dp[u][0]+=a[u];dp[u][1]+=a[u];
		int v=G[u][i];
		t0=min(t0,dp[v][1]);
		t1=max(t1,dp[v][0]);
		if(v!=fa) dfs1(v,u);
	}
}
int main() {
    
    
    //freopen("input.in","r",stdin);
	for(scanf("%d",&_);_;_--) {
    
    
		scanf("%d",&n);rep(i,1,n) G[i].clear(),kk[i].clear();
		rep(i,1,n) scanf("%lld",&a[i]);
		rep(i,1,n) scanf("%lld",&b[i]),a[i]-=b[i];
		rep(i,2,n) {
    
    
			int u,v;scanf("%d%d",&u,&v);
			G[u].pb(v);G[v].pb(u);
		}
		dfs(1,-1);ans=dp[1][0];
		dfs1(1,-1);
		printf("%lld\n",ans);
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/qq_43914084/article/details/107043258