[CF1394D] Boboniu and Jianghu
D - Boboniu and Jianghu
设\(dp[i][0/1]\)表示当前链从下往上是不增/减的,那么当\(u\)与\(v\)(其中\(fa[v]=u\))的\(b\)不相同时,\(dp[v][0/1]\)的第二维转移的状态是确定的,否则就是不确定的,这时直接强制其取\(0\),然后向每个点的\(vector\)中加入\(dp[v][1]-dp[v][0]\),从小到大排序,然后每次取前缀和的来改变转移的这些\(dp[v][0/1]\)的第二维的取值
转移时,对于取\(a[i]\)的个数,设\(cnt0\)和\(cnt1\)分别表示转移状态中第二维取\(0\)或\(1\)的个数,那么这也可以表示为第\(i\)个点的入度和出度,对于\(dp[i][0]\),\(a[i]\times\max(cnt0,cnt1+(i\neq1))\),对于\(dp[i][1]\),\(a[i]\times\max(cnt0+(i\neq1),cnt1)\),因为这些入的链可以在\(u\)处和出的链链接上
#include<bits/stdc++.h>
#define ll long long
#define pb push_back
using namespace std;
const int N=2e5+5;
const ll INF=1e18;
int n,a[N],b[N];
int head[N],cnt=1;
struct node{
int nxt,v;
}tree[N<<1];
void add(int u,int v){
tree[++cnt]={head[u],v},head[u]=cnt;
tree[++cnt]={head[v],u},head[v]=cnt;
}
ll dp[N][2];
void dfs(int u,int fa){
ll sum=0;
int cnt0=0,cnt1=0;
vector<ll> val;
for(int i=head[u],v;i;i=tree[i].nxt){
if((v=tree[i].v)==fa) continue;
dfs(v,u);
if(b[u]>b[v]) sum+=dp[v][1],++cnt1;
else if(b[u]<b[v]) sum+=dp[v][0],++cnt0;
else sum+=dp[v][0],val.pb(dp[v][1]-dp[v][0]),++cnt0;
}
sort(val.begin(),val.end());
for(int i=0;i<=val.size();++i){
dp[u][0]=min(dp[u][0],sum+1ll*max(cnt0,cnt1+(u!=1))*a[u]);
dp[u][1]=min(dp[u][1],sum+1ll*max(cnt0+(u!=1),cnt1)*a[u]);
--cnt0,++cnt1;
if(i==val.size()) continue;
sum+=val[i];
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&a[i]),dp[i][0]=dp[i][1]=INF;
for(int i=1;i<=n;++i) scanf("%d",&b[i]);
for(int i=1,u,v;i<n;++i) scanf("%d%d",&u,&v),add(u,v);
dfs(1,0);
printf("%lld",min(dp[1][0],dp[1][1]));
return 0;
}

浙公网安备 33010602011771号