开始题目没看清楚,这句话没有理解清楚->Bank x is neighboring to some offline bank.意思就是除了第一外,其他hack的只能是之前hack的邻居,然后我们就发现了只有+1和+2的两种增幅。从第一个点开始扫,然后找以每个点开始的最大值(它自己本身,它的直接邻居+1,其他+2,中取最大值)。所有最大值中的最小值就是我们要求的。然后中间用数组来扫的话就会超时,然后就用了multiset,和set的用法基本相同,然后它可以存重复数据,其中
multiset ms;
ms.count(k)//的值可能大于1;
ms.erase(k);//删除其中的一个k,有可能还有k
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
#include <cstdio>
#include <cmath>
using namespace std;
const int maxn = 300005;
#define INF 0x3f3f3f3f
struct node
{
int to,pre;
};
node e[maxn*2];
int head[maxn];
long long a[maxn];
int vis[maxn];
int mis[maxn];
multiset <long long> ms;
void add(int h,int a,int b)
{
e[h].to=b;e[h].pre=head[a];head[a]=h;
}
int main()
{
int n;
scanf("%d",&n);
memset(head,-1,sizeof(head));
for(int i=1;i<=n;i++)
{
scanf("%I64d",&a[i]);
ms.insert(a[i]);
}
int h=0;
for(int i=0;i<n-1;i++)
{
int a1,b;
scanf("%d %d",&a1,&b);
add(h,a1,b);h++;
add(h,b,a1);h++;
}
long long ans=INF;
multiset<long long>:: iterator it;
for(int i=1;i<=n;i++)
{
long long temp=a[i];
vis[i]=1;
it=ms.find(a[i]);
ms.erase(it);
for(int j=head[i];j>-1;j=e[j].pre)
{
node gg=e[j];
temp=max(temp,a[gg.to]+1);
it=ms.find(a[gg.to]);
ms.erase(it);
}
if(!ms.empty()){
it=ms.end();
it--;
temp=max(temp,*it+2);
}
ans=min(ans,temp);
for(int j=head[i];j>-1;j=e[j].pre)
{
node gg=e[j];
ms.insert(a[gg.to]);
}
ms.insert(a[i]);
}
ms.clear();
cout<<ans<<endl;
return 0;
}