CodeForces - 796C Bank Hacking(思路)

描述

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.

img

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 a**i.

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:

  1. Bank x is online. That is, bank x is not hacked yet.
  2. Bank x is neighboring to some offline bank.
  3. 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.

Input

The first line contains one integer n (1 ≤ n ≤ 3·105) — the total number of banks.

The second line contains n integers a1, a2, …, a**n ( - 109 ≤ a**i ≤ 109) — the strengths of the banks.

Each of the next n - 1 lines contains two integers u**i and v**i (1 ≤ u**i, v**i ≤ n, u**i ≠ v**i) — meaning that there is a wire directly connecting banks u**i and v**i.

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.

Output

Print one integer — the minimum strength of the computer Inzane needs to accomplish the goal.

input

5
1 2 3 4 5
1 2
2 3
3 4
4 5

output

5

input

7
38 -29 87 93 39 28 -55
1 2
2 5
3 2
2 4
1 7
7 6

output

93

input

5
1 2 7 6 7
1 5
5 3
3 4
2 4

output

8

Note

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.

思路

給了一棵n個節點的樹,每個節點有一個權值。定義兩個概念:

  • 相鄰:i節點和j節點直接有邊相連
  • 半相鄰:i和k有一條邊,k和j有一條邊則i和j相鄰,且k在線

每次挑一個節點hack掉,然後與他半相鄰和相鄰的所有的節點的權值會加1,然後這個點就成了離線狀態。刪點的規則是:

  • x點還沒被刪
  • x是離線的點的鄰居
  • x的權值小於等於你的初始強度

若當u的祖先被攻擊時,u最多+2,此時它的任意子結點v,只有當u被攻擊時才能被攻擊,子節點對u貢獻爲0
若爲u的某個子樹被攻擊,u的其餘子樹和u的祖先 都只有在u被攻擊時才被攻擊,所以任意點u的值最多+2,ans<=mx+2

先用multiset插入所有的權值,對於每一個點,都暴力一下求一下當前點的maxx的值,最後取一個最小就是答案。暴力的方法是先從集合中刪除當前點,在刪除這個點的所有相連的點,求一下這個點和它的子節點的最大值加一的最大值(因爲這一層最多產生貢獻1),對於剩下的點,求一個找到最大值加2,求最大值。最後把刪除的點插入回來。這樣每個點爲根的值都可以求出來,我們求出最優的就行了。

代碼

#include <bits/stdc++.h>
using namespace std;
const int inf = 2e9 + 10;
const int N = 300000 + 10;
int a[N];
vector<int> e[N];
multiset<int> s;
int main()
{
    int n, u, v;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        s.insert(a[i]);
    }
    for (int i = 1; i <= n - 1; i++)
    {
        scanf("%d%d", &u, &v);
        e[u].push_back(v);
        e[v].push_back(u);
    }
    int ans = inf;
    for (int i = 1; i <= n; i++)
    {
        int maxx = a[i];
        s.erase(s.find(a[i]));
        for (auto v : e[i])
        {
            maxx = max(maxx, a[v] + 1);
            s.erase(s.find(a[v]));
        }
        if (s.size())
            maxx = max(maxx, *s.rbegin() + 2);
        s.insert(a[i]);
        for (auto v : e[i])
            s.insert(a[v]);
        ans = min(ans, maxx);
    }
    printf("%d\n", ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章