题目大意:
n家银行有n-1条网线相连,最初第i家银行的实力为a[i],且所有银行都在线。如果i和j有一条网线直接相连,则相邻;若i和k相邻,k和j相邻,则称i和j次相邻。当银行被攻击后,立即断线,与其相邻、次相邻的银行实力加1。现在Inzane开始他hack所有银行的计划,他选择hack的银行,需要满足3个条件:这家银行仍在线;它的相邻银行已经被hack;自己的实力需不低于银行实力。问:Inzane的实力至少为多少才能完成计划?
题解:
题目繁冗,简单来说就是,他任意选择一家银行开始实施计划,剩下的银行必须与hack过的银行相邻,即有一定顺序。记目前被攻击的银行为i,相邻银行为j,次相邻银行为k,且j和k未被攻击,据题意,k银行的实力最终会且只会+2(i银行被攻击时+1,j银行被攻击时再+1)。所以,答案必然为max,max+1,max+2中的一个值。[答案为max的情况是,只有一家银行的实力为max,且实力为max-1的银行全部与其相邻。答案为max+1的情况是,某家实力为max的银行,与其余所有实力为max的银行相邻。其余情况全部为max+2。]
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 3 * 1e5 + 5;
vector <int> v[300005];
int num[maxn][3];
int main()
{
int n,x,y,sum1,sum2,a[maxn];
scanf("%d",&n);
int maxv=-1000000001,maxno=0;
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if (a[i]>maxv)
{
maxv=a[i];
maxno=i;
}
}
for (int i=1;i<n;i++)
{
scanf("%d %d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
int tot1=0,tot2=0;
for (int i=1;i<=n;i++)
{
if (a[i]==maxv) tot1++;
if (a[i]==maxv-1) tot2++;
}
for (int i=1;i<=n;i++)
{
sum1=0,sum2=0;
if (a[i]==maxv) sum1++;
if (a[i]==maxv-1) sum2++;
int m=v[i].size();
for (int j=0;j<m;j++)
{
if (a[v[i][j]]==maxv) sum1++;
if (a[v[i][j]]==maxv-1) sum2++;
}
num[i][1]=sum1;
num[i][2]=sum2;
}
if (tot1==1)
{
if (num[maxno][2]==tot2)
{
printf("%d",maxv);
return 0;
}
}
for (int i=1;i<=n;i++)
if (num[i][1]==tot1)
{
printf("%d",maxv+1);
return 0;
}
printf("%d",maxv+2);
return 0;
}
题意要理解正确,不然就只有wa了