(CodeForces ) C. Bank Hacking
阿新 • • 發佈:2018-12-11
題目大意:一個聯通網路,每個點都有權值,破壞一個點,需要有>=改點權值的強度,破壞一個點之後,它會給他範圍為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; }