1. 程式人生 > >Codeforces Round #525 (Div. 2) E. Ehab and a component choosing problem(貪心+樹形dp)

Codeforces Round #525 (Div. 2) E. Ehab and a component choosing problem(貪心+樹形dp)

E. Ehab and a component choosing problem

time limit per test

1 second

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. You want to choose an integer kk (1≤k≤n)(1≤k≤n) and then choose kk connected components of nodes that don't overlap (i.e every node is in at most 1 component). Let the set of nodes you chose be ss. You want to maximize:

 

∑u∈sauk∑u∈sauk

In other words, you want to maximize the sum of weights of nodes in ss divided by the number of connected components you chose. Also, if there are several solutions, you want to maximize kk.

Note that adjacent nodes can belong to different components. Refer to the third sample.

Input

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

The second line contains nn space-separated integers a1a1, a2a2, ……, anan (|ai|≤109)(|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

Print the answer as a non-reduced fraction represented by 2 space-separated integers. The fraction itself should be maximized and if there are several possible ways, you should maximize the denominator. See the samples for a better understanding.

Examples

input

Copy

3
1 2 3
1 2
1 3

output

Copy

6 1

input

Copy

1
-2

output

Copy

-2 1

input

Copy

3
-1 -1 -1
1 2
2 3

output

Copy

-3 3

input

Copy

3
-1 -2 -1
1 2
1 3

output

Copy

-2 2

Note

A connected component is a set of nodes such that for any node in the set, you can reach all other nodes in the set passing only nodes in the set.

In the first sample, it's optimal to choose the whole tree.

In the second sample, you only have one choice (to choose node 1) because you can't choose 0 components.

In the third sample, notice that we could've, for example, chosen only node 1, or node 1 and node 3, or even the whole tree, and the fraction would've had the same value (-1), but we want to maximize kk.

In the fourth sample, we'll just choose nodes 1 and 3.

題意:

給你n個結點的權值,再給你n-1條無向無權邊(保證構成一棵樹),讓你找k個互不相交的連通塊,使得這k個連通塊中的每個連通塊的節點的權值和都相等且最大。也就是說,找一個最大權值的連通塊,然後找與它互不相交的連通塊且權值相同的有幾個。輸出這些連通塊的總權值和連通塊的個數。

思路:

感覺就是純閱讀理解,讀懂題意之後就變得很簡單了:

利用貪心思想,先dp一遍求出以i為根的連通塊的最大權值,然後再dp一遍求有多少個和最大值相同的連通塊即可。

程式碼中的許多細節還需要自己慢慢體會。

程式碼:

#include <bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f3f3f3f3fLL
using namespace std;
const int maxn=3e5+10;
vector<ll>vc[maxn];
ll a[maxn],dp[maxn],c[maxn];
int n;
bool jud;
ll ans,cnt;
ll dfs(int u,int fa)
{
    dp[u]=a[u];
    for(int i=0;i<vc[u].size();i++)
    {
        int v=vc[u][i];
        if(v!=fa) {
        dfs(v,u);
        if(dp[v]>0) dp[u]+=dp[v];
        }
    }
    ans=max(ans,dp[u]);
    if(jud&&dp[u]==ans)
    {
        dp[u]=0;
        cnt++;
    }
    return dp[u];
}
int main()
{
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[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=-inf;cnt=0;
    dfs(1,0);
    jud=1;
    dfs(1,0);
    printf("%lld %lld\n",ans*cnt,cnt);
    return 0;
}