Codeforces Round #525 (Div. 2) F. Ehab and a weird weight formula(思维+贪心)

F. Ehab and a weird weight formula

time limit per test

2.5 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You're given a tree consisting of nn nodes. Every node uu has a weight auau. It is guaranteed that there is only one node with minimum weight in the tree. For every node uu (except for the node with the minimum weight), it must have a neighbor vv such that av<auav<au. You should construct a tree to minimize the weight ww calculated as follows:

  • For every node uu, degu⋅audegu⋅au is added to ww (degudegu is the number of edges containing node uu).
  • For every edge {u,v}{u,v}, ⌈log2(dist(u,v))⌉⋅min(au,av)⌈log2(dist(u,v))⌉⋅min(au,av) is added to ww, where dist(u,v)dist(u,v) is the number of edges in the path from uuto vv in the given tree.

Input

The first line contains the integer nn (2≤n≤5⋅105)(2≤n≤5⋅105), the number of nodes in the tree.

The second line contains nn space-separated integers a1,a2,…,ana1,a2,…,an (1≤ai≤109)(1≤ai≤109), the weights of the nodes.

The next n−1n−1 lines, each contains 2 space-separated integers uu and vv (1≤u,v≤n)(1≤u,v≤n) which means there's an edge between uu and vv.

Output

Output one integer, the minimum possible value for ww.

Examples

input

Copy

3
1 2 3
1 2
1 3

output

Copy

7

input

Copy

5
4 5 3 7 8
1 2
1 3
3 4
4 5

output

Copy

40

Note

In the first sample, the tree itself minimizes the value of ww.

In the second sample, the optimal tree is:

题意:

给你一颗包含n个节点的无向树,每个节点都有值。保证这棵树除了最小值节点,其他节点均存在一条邻边,使得边的另一点的值比它小。现在让你重构这棵树,使得总权值最小。

总权值=每个节点的值*这个节点的度+每条边的权值*min( log2(其一点u到另任意一点v的最小距离)*点v的值 )。

思路:

由红色部分我们可以得出,当确定最小值的节点为根以后,从根往下每个节点的权值一定是依次增大的。所以就可以采用近似贪心的思想,

考虑将两种贡献直接一次按每条边的贡献算,则对于任意点对(u,v),设a[u]>a[v],

则总权值=a[u]+min(a[v]+a[v]*log2(dist[u][v]))  注意log2是向上取整(题干中有说),所以一次直接枚举u的第2的i次方个祖先节点,对于每2的i次方个祖先,深度越低的祖先权值越小,所以枚举i,都是直接用u的第2的i次方的祖先来当v(即重新构的图中,u直接连向v)。

注意根节点要特判。(因为可能不是正好是u的第2的整数次方个祖先)

最终总复杂度是O(nlogn)。

说难也不难,但是思维难度很高,还需要更多的思考和练习。

#include <bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f3f3f3f3fLL
using namespace std;
const int maxn=5e5+10;
vector<ll>vc[maxn];
ll a[maxn],dp[maxn][21],c[maxn];
int n,rt;
bool jud;
ll ans,cnt;
void dfs(int u,int fa)
{
    dp[u][0]=fa;
    for(int i=1;i<=20;i++)
    {
        if(dp[u][i-1]==-1) break;
        dp[u][i]=dp[dp[u][i-1]][i-1];
    }
    ll mi=inf;
    for(int i=0;i<=20;i++)
    {
        mi=min(mi,a[u]+(ll)(i+1)*a[dp[u][i]]);
        if(dp[u][i+1]==-1)
        {
            mi=min(mi,a[u]+(ll)a[rt]*(i+2));
            break;
        }
    }
    if(u!=rt) ans+=mi;
    for(int i=0;i<vc[u].size();i++)
    {
        int v=vc[u][i];
        if(v!=fa) {
        dfs(v,u);
        }
    }
}
int main()
{
    scanf("%d",&n);
    rt=1;
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        if(a[i]<a[rt]) rt=i;
    }
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        vc[x].push_back(y);
        vc[y].push_back(x);
    }
    ans=0;
    memset(dp,-1,sizeof(dp));
    dfs(rt,-1);
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/LSD20164388/article/details/84989417