含
n
个点的树,每个点的权值可为
尺取+贪心+树形dp
#include<cstring>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf=0x7fffffff;
const int M=100005;
typedef long long ll;
struct Edge{
int to,nxt;
}edge[M<<1];
int last[M],allc;
int n;
void ins(int u,int v){
edge[++allc]=(Edge){v,last[u]};last[u]=allc;
}
int dat[M][2];
ll dp[M][2];
bool cmp(int x,int y){
return dat[x][1]<dat[y][1];
}
struct node{
int id,val;
long long ans;
bool operator<(const node&a)const{
return val<a.val;
}
}num[M<<1];
int tot;
int cnt[M];
ll res[M];
ll ans,ans1,ans0;
void solve(int x,int K){
ans=0;
int sum=tot>>1;//必须同时满足sum个不同id决策存在
int mx,top=0;
for(int i=0;i<tot;i++)
cnt[num[i].id]=0;
for(int id,i=0;i<tot;i++){
//枚举最小值
mx=num[i].val+K*1000;
while(top<tot){
if(num[top].val<=mx){
id=num[top].id;
cnt[id]++;
if(cnt[id]==1){
res[id]=num[top].ans;
ans+=res[id];
sum--;//该id的决策存在
}
if(cnt[id]==2){
ans-=res[id];//
res[id]=max(dp[id][0],dp[id][1]);
ans+=res[id];
}
top++;
}
else break;
}
if(!sum){//所有决策均已满足
if(dat[x][0]>=num[i].val)
ans0=max(ans+dat[x][0]-1ll*K*666*x,ans0);
if(dat[x][1]<=mx)
ans1=max(ans+dat[x][1]-1ll*K*666*x,ans1);
}
id=num[i].id;
cnt[id]--;
if(cnt[id]==0){
ans-=res[id];
sum++;
}
if(cnt[id]==1){
ans-=res[id];
res[id]=dp[id][1];
ans+=res[id];
}
}
}
void dfs(int x,int f){
for(int i=last[x];i;i=edge[i].nxt){
int y=edge[i].to;
if(y==f)continue;
dfs(y,x);
}
tot=0;
for(int i=last[x];i;i=edge[i].nxt){
int y=edge[i].to;
if(y==f)continue;
for(int j=0;j<2;j++)
num[tot++]=(node){y,dat[y][j],dp[y][j]};
}
if(!tot){
for(int j=0;j<2;j++)
dp[x][j]=dat[x][j];
return;
}
for(int j=0;j<2;j++)
num[tot++]=(node){x,dat[x][j],0};
sort(num,num+tot);
ans1=ans0=-1ll*inf*inf;
dp[x][0]=dp[x][1]=0;
for(int i=0;i<101;i++)solve(x,i);
dp[x][0]=ans0;
dp[x][1]=ans1;
return;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=0;j<2;j++)
scanf("%d",&dat[i][j]);
if(dat[i][0]>dat[i][1])swap(dat[i][0],dat[i][1]);
}
for(int u,v,i=1;i<n;i++){
scanf("%d%d",&u,&v);
ins(u,v);ins(v,u);
}
dfs(1,0);
printf("%lld\n",max(dp[1][0],dp[1][1]));
return 0;
}