线段树维护贪心
/* */
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<cmath>
#include<set>
#define ll long long
#define M 500010
#define mmp make_pair
#define INF 1000000000
using namespace std;
int read() {
int nm = 0, f = 1;
char c = getchar();
for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
return nm * f;
}
vector<int> v[M] ;
int h[M], hm[M], st_tmp[M], scnt ;
struct P {
int id, hm ;
bool operator < (const P &rhs) const {
return hm<rhs.hm ;
}
} cave[M]; void dfs0(int x, int f, int nowh) {
hm[x]=nowh ;
for(auto i : v[x]) if(i != f)
dfs0(i, x, min(nowh, h[i])) ;
}
int tmp[M], tcnt ;
void dfs2(int x, int f, int nowhm) {
tmp[tcnt++]=nowhm ;
for(auto i : v[x]) if(i != f) {
int newhm=min(nowhm, h[i]) ;
if(newhm > hm[i]) dfs2(i, x, newhm) ;
}
} multiset<int> st ;
bool check() {
if(tcnt < st.size()) return 0 ;
scnt=0 ;
for(int i=0; !st.empty() && i<tcnt; i++) {
auto it=st.upper_bound(tmp[i]) ;
if(it != st.begin())
it-- , st_tmp[scnt++]=*it , st.erase(it) ;
}
int sz=st.size() ;
for(int i=0; i<scnt; i++) st.insert(st_tmp[i]) ;
return sz==0 ;
} int LIM ;
bool dfs(int x, int f, int add) {
if(h[x]<=LIM) {
int newhm= (f==-1 ? h[x]+add : min(hm[f], h[x]+add)) ;
if(newhm>hm[x]) {
tcnt=0 ;
dfs2(x, f, newhm) ;
if(check()) return 1 ;
}
}
for(auto i : v[x]) if(i != f && dfs(i, x, add))
return 1 ;
return 0 ;
} main() {
int n = read();
for(int i=1; i<=n; i++) h[i] = read();
for(int i=1; i<n; i++) {
int x = read(), y = read();
v[x].push_back(y) ;
v[y].push_back(x) ;
}
dfs0(1, -1, h[1]) ; int k = read();
for(int i=1, x; i<=k; i++) x = read(), st.insert(x) ;
for(int i=k+1; i<=n; i++) st.insert(0) ;
for(int i=1; i<=n; i++) cave[i]=(P) {
i, hm[i]
} ;
sort(cave+1, cave+n+1) ; LIM=-1 ;
for(int i=1; i<=n; i++) {
auto it=st.upper_bound(cave[i].hm) ;
if(it != st.begin()) st.erase(--it) ;
else if(LIM==-1) LIM=cave[i].hm ;
}
if(st.empty()) {
printf("0\n") ;
return 0;
}
if(!dfs(1, -1, INF)) {
printf("-1\n") ;
return 0 ;
} int l=0 , r=INF ;
while(r-l>1) {
int mid=(r+l)/2 ;
if(dfs(1, -1, mid)) r=mid ;
else l=mid ;
}
printf("%d\n", r) ;
}

最新文章

  1. Shou.TV 招聘【北京】— — 生效中
  2. js中替换返回json中的空格为&amp;nbsp;
  3. Xcode快捷键大全
  4. Qt编写可换肤的中文双拼汉字输入法
  5. HTML元素的ID和Name属性的区别
  6. linux 内核协议栈收报流程(一)ixgbe网卡驱动
  7. 南京邮电大学java第四次实验报告
  8. react-navigation 简介
  9. thinkcmf 相关
  10. 改变this的指向问题;
  11. P4145 上帝造题的七分钟2 / 花神游历各国
  12. TF-IDF算法-golang实现
  13. Java之——Web项目中DLL文件动态加载方法
  14. Win10安装MySQL5.7.22 解压缩版(手动配置)方法
  15. ionic和angularjs的区别?
  16. Bootstrap 按钮组
  17. Linq基础操作之Select,Where,OrderBy,ThenBy源码分析
  18. BZOJ 2457 双端队列
  19. js常用算法
  20. DDD学习笔录——简介DDD的战术模式、问题空间和解空间

热门文章

  1. [转]Jboss基础
  2. 将react升级到15之后的坑
  3. css 新单位 fr
  4. Android Monkey测试入门
  5. php调用C#生成的dll(二)
  6. EntityFrameworkCore操作记录
  7. C#:单元测试(VS2015)
  8. windows系统如何设置域名解析
  9. SparkStreaming整合kafka编程
  10. RedHat6.5安装Spark单机