思路:我们很容易能发现,任意选则一个点的话,那么该点所需的能力值为a[i],与它相邻所需的能力值为a[i]+1,其余都是a[i]+2,所以答案只有三种,必定是max,max+1,max+2。
max:只存在一个点的权值是max,相邻的点包含了全部max-1的点。
max+1:存在一个点,它与它相邻的点包含了全部权值为max的点。
其余情况均为max+2。下面给代码:
#include<iostream>
#include<cmath>
#include<queue>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
#include<string>
#include<utility>
#include<map>
#include<vector>
#define maxn 300005
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const double eps = 1e-8;
int a[maxn], head[maxn], len, maxnum, sum, sum1, index, cal, vis[maxn];
struct node{
int v, next;
}p[maxn << 1];
void addedge(int u, int v){
p[len].v = v;
p[len].next = head[u];
head[u] = len++;
}
int main(){
int n;
scanf("%d", &n);
memset(head, -1, sizeof(head));
maxnum = -inf;
for (int i = 1; i <= n; i++){
scanf("%d", &a[i]);
maxnum = max(maxnum, a[i]);
}
for (int i = 1; i <= n; i++){
if (a[i] == maxnum){
sum++;
index = i;
}
else if (a[i] == maxnum - 1)
sum1++;
}
for (int i = 0; i < n - 1; i++){
int u, v;
scanf("%d%d", &u, &v);
addedge(u, v);
addedge(v, u);
}
int judge = 2;
if (sum == 1){
for (int i = head[index]; ~i; i = p[i].next){
if (a[p[i].v] == maxnum - 1)
cal++;
}
if (cal == sum1)
judge = 0;
else
judge = 1;
}
else{
for (int i = 1; i <= n; i++){
if (a[i] == maxnum){
vis[i]++;
if (vis[i] == sum){
judge = 1;
break;
}
for (int j = head[i]; ~j; j = p[j].next){
vis[p[j].v]++;
if (vis[p[j].v] == sum){
judge = 1;
break;
}
}
if (judge == 1)
break;
}
}
}
printf("%d\n", maxnum + judge);
}