Although Inzane successfully found his beloved bone, Zane, his owner, has yet to return. To search for Zane, he would need a lot of money, of which he sadly has none. To deal with the problem, he has decided to hack the banks.
There are n banks, numbered from 1 to n. There are also n - 1 wires connecting the banks. All banks are initially online. Each bank also has its initial strength: bank i has initial strength ai.
Let us define some keywords before we proceed. Bank i and bank j are neighboring
if and only if there exists a wire directly connecting them. Bank i and bank j are
semi-neighboring if and only if there exists an online bank k such that bank i and
bank k are neighboring and bank k and bank j are neighboring.
When a bank is hacked, it becomes offline (and no longer online), and other
banks that are neighboring or semi-neighboring to it have their strengths increased by 1.
To start his plan, Inzane will choose a bank to hack first. Indeed, the strength
of such bank must not exceed the strength of his computer. After this, he will
repeatedly choose some bank to hack next until all the banks are hacked, but
he can continue to hack bank x if and only if all these conditions are met:
- Bank x is online. That is, bank x is not hacked yet.
- Bank x is neighboring to some offline bank.
- The strength of bank x is less than or equal to the strength of Inzane's
- computer.
Determine the minimum strength of the computer Inzane needs to hack all
the banks.
The first line contains one integer n (1 ≤ n ≤ 3·105) — the total number of banks.
The second line contains n integers a1, a2, ..., an ( - 109 ≤ ai ≤ 109) — the strengths of the banks.
Each of the next n - 1 lines contains two integers ui and vi (1 ≤ ui, vi ≤ n, ui ≠ vi) —
meaning that there is a wire directly connecting banks ui and vi.
It is guaranteed that the wires connect the banks in such a way that Inzane can
somehow hack all the banks using a computer with appropriate strength.
Print one integer — the minimum strength of the computer Inzane needs to
accomplish the goal.
5 1 2 3 4 5 1 2 2 3 3 4 4 5
5
7 38 -29 87 93 39 28 -55 1 2 2 5 3 2 2 4 1 7 7 6
93
5 1 2 7 6 7 1 5 5 3 3 4 2 4
8
In the first sample, Inzane can hack all banks using a computer with strength 5. Here is how:
- Initially, strengths of the banks are [1, 2, 3, 4, 5].
- He hacks bank 5, then strengths of the banks become [1, 2, 4, 5, - ].
- He hacks bank 4, then strengths of the banks become [1, 3, 5, - , - ].
- He hacks bank 3, then strengths of the banks become [2, 4, - , - , - ].
- He hacks bank 2, then strengths of the banks become [3, - , - , - , - ].
- He completes his goal by hacking bank 1.
In the second sample, Inzane can hack banks 4, 2, 3, 1, 5, 7, and 6, in this order. This way, he can hack all banks using a computer with strength 93.
能攻击的点满足下列情况:
1。该点未被攻击过。
2.该点防御力小于主角的攻击力。
3.该点与被摧毁的点相连。
每次攻击完一个点后,与之相邻一个单位的点防御力会加1,与之相邻两个单位的点的防御力也会加一。
求主角将所以点攻破需要的最小攻击力。课任意选择第一个攻击点。
题解:最开始攻击的点一定要选择防御力最大点。全部攻击完成后,与最开始相比,最大值的那个点的防御力不变,
与最大值相邻的点的防御力+1,其余点防御力+2。因此:结果只可能为最大值maxnn,或者maxnn + 1,maxnn + 2中的结果。
1.当最大值只有一个的时候:若与最大值相邻的点中值为maxnn - 1的点的个数与总的值为maxnn - 1的个数相同,
则结果为maxnn,否则为maxnn - 1。
2.当最大值大于一个的时候:若与某一点相连的点中最大值的点的个数等于总的最大值的点的个数,则结果为maxnn + 1。
否则为maxxn + 2。
还要注意本题的循环要从i = 1开始,因为最小的点的编号从1开始编号。我刚开始从0 - n循环就WA,
然后找了好久才找出这个错误。以后做题要注意这个。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
const int maxn = 3 * 1e5 + 5;
int a[maxn];
vector<int> mapn[maxn];
int main()
{
int n;
int i,j;
while(scanf("%d",&n) != EOF)
{
for(i = 1;i <= n;i++) mapn[i].clear();
int x,y;
int maxnn = -1e9 - 5;
for(i = 1;i <= n;i++)
{
scanf("%d",&a[i]);
if(maxnn < a[i])
{
maxnn = a[i];
}
}
for(i = 1;i <= n - 1;i++)
{
scanf("%d%d",&x,&y);
mapn[x].push_back(y);
mapn[y].push_back(x);
}
int N_maxn,n_maxn;
N_maxn = n_maxn = 0;
for(i = 1;i <= n;i++)
{
if(a[i] == maxnn) N_maxn++;
if(a[i] == maxnn - 1) n_maxn++;
}
if(N_maxn == 1)
{
int v;
int coun = 0;
for(i = 1;i <= n;i++)
{
if(a[i] == maxnn) v = i;
}
for(i = 0;i < mapn[v].size();i++)
{
if(a[mapn[v][i]] == maxnn - 1) coun++;
}
if(coun == n_maxn) printf("%d\n",maxnn);
if(coun < n_maxn) printf("%d\n",maxnn + 1);
}
else
{
int coun;
int flag = 0;
for(i = 1;i <= n;i++)
{
coun = 0;
if(a[i] == maxnn) coun++;
for(j = 0;j < mapn[i].size();j++)
{
if(a[mapn[i][j]] == maxnn) coun++;
}
if(coun == N_maxn) flag = 1;
}
if(flag)
{
printf("%d\n",maxnn + 1);
}
else
{
printf("%d\n",maxnn + 2);
}
}
}
return 0;
}