擦彩网站开发,cms自助建站,建设制作网站,什么是同ip网站我们在树上的每个点iii上放aia_iai个小点#xff0c;初始时先让每个点单独减#xff0c;这样要花费aia_iai之和的次数。
然后尝试把某些减合并。一个点上面的小点至多可以向两个相邻的小点连边#xff08;这两个小点不能在同一个点上#xff09;。每连一条边#xff…我们在树上的每个点iii上放aia_iai个小点初始时先让每个点单独减这样要花费aia_iai之和的次数。
然后尝试把某些减合并。一个点上面的小点至多可以向两个相邻的小点连边这两个小点不能在同一个点上。每连一条边合并次数1答案-1。
问题变成求一棵树内的最大合并次数。
首先明确该问题满足最优子结构即考虑以UUU为根的子树时若U,VU,VU,V上的小点u,vu,vu,v可以合并合并u,vu,vu,v 一定不比 不合并u,vu,vu,v以让fau,ufa_u,ufau,u合并 劣。 感性证明faufa_ufau可能可以和不是uuu的其它小点合并即使找不到其它可以合并的小点前面的方案也不必后面的方案劣。
设gig_igi表示考虑完以iii为根的子树在合并次数最多的情况下iii上最多有几个小点能和iii的父亲上的小点合并。转移讨论一下即可。
#includeiostream
#includecstdio
using namespace std;
typedef long long ll;
const int N2e510;
struct Edge{int v,nxt;}e[N1];
int cnt,head[N],n;
ll ans,a[N];
void adde(int u,int v){e[cnt].vv;e[cnt].nxthead[u];head[u]cnt;
}
void dfs(int u,int fa){ll sum0,maxn0,pr;for(int ihead[u];i;ie[i].nxt){int ve[i].v;if(vfa)continue;dfs(v,u);suma[v],maxnmax(maxn,a[v]);}if(sum-maxnmaxn) prsum/2;else prsum-maxn;if(suma[u]) ans-sum;else{prmin(pr,min(sum-a[u],a[u]));ans-a[u]pr;a[u]-pr;}
}
int main(){scanf(%d,n);for(int i1;in;i){scanf(%lld,a[i]);ansa[i];}for(int i1;in;i){int u,v;scanf(%d%d,u,v);adde(u,v);adde(v,u);}dfs(1,0);printf(%lld\n,ans);return 0;
}