题目大意:一个联通网络,每个点都有权值,破坏一个点,需要有>=改点权值的强度,破坏一个点之后,它会给他范围为2的点都+1。问最小需要的强度大小。
解题思路:这道题我们可以贪心的来想,如果最大的点max唯一,我们肯定要先破坏最大的那个点max,如果先去破坏比较小的点,最后破坏最大点的强度会变大,我们需要的强度反而会变得更高。但是如果最大的点不唯一,那就再需要考虑一下了。
具体情形如下:
一.最大的点唯一为max;
1.次小的点为max-1,且全部出现在,max的范围1内,则需要的强度大小为max;
2.不满足1,那么需要的强度大小为max+1;
二.最大的点不唯一为max;
1.如果最大的点都出现在一个较小的点范围1内,或者其他全部最大的点都出现在一个最大的点范围1内,则需要的强度为 max+1;
2.不满足1,那么需要的强度大小为max+2;
可以自己带着画图去理解。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=3e5+5;
int n,tmp;
vector<int> ee[maxn];
struct node {
int id;
int w;
} a[maxn];
int lo[maxn];
int main() {
scanf("%d",&n);
int num1=0,num2=0,maxnum=-2e9;
for(int i=1; i<=n; ++i) {
scanf("%d",&tmp);
a[i]=node {i,tmp};
maxnum=max(maxnum,tmp);
}
int x,y;
for(int i=1; i<=n-1; ++i) {
scanf("%d%d",&x,&y);
ee[x].push_back(y);
ee[y].push_back(x);
}
for(int i=1; i<=n; ++i) {
if(a[i].w==maxnum) lo[num1++]=a[i].id;
if(a[i].w==maxnum-1) num2++;
}
if(num1==1) {
int tmp=0;
for(int i=0; i<(int)ee[lo[0]].size(); ++i) {
int np=ee[lo[0]][i];
if(a[np].w==maxnum-1) tmp++;
}
if(tmp==num2) {
cout<<maxnum<<endl;
} else {
cout<<maxnum+1<<endl;
}
}
else {
bool flag=false;
for(int i=1;i<=n;++i){
int tmp=0;
if(a[i].w==maxnum){
for(int j=0;j<(int)ee[i].size();++j){
int np=ee[i][j];
if(a[np].w==maxnum) tmp++;
}
if(tmp==num1-1){
flag=true;
break;
}
}
else{
for(int j=0;j<(int)ee[i].size();++j){
int np=ee[i][j];
if(a[np].w==maxnum) tmp++;
}
if(tmp==num1){
flag=true;
break;
}
}
}
if(flag) {
cout<<maxnum+1<<endl;
} else {
cout<<maxnum+2<<endl;
}
}
return 0;
}