C
来源:互联网 发布:男友忙后没时间 知乎 编辑:程序博客网 时间:2024/06/01 18:56
开始题目没看清楚,这句话没有理解清楚->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 0x3f3f3f3fstruct 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;}
0 0