問題の意味
ツリーから選択します。 ように、通信ブロック 大規模な基礎としてでは、できるだけ大きく、聞かせて できるだけ大きく
問題の解決策
あなたが選択した場合我々は、明らかに逆小隊の収集、検討してください
、最初は選択します
。
ので、大きさの比較
受注
あなたは見つけるでしょう、
条件を知られている、のみ最適であることを選択しました。
しかし
最大値の複数の要件のセットから選択されるように、良好です。
しようとしています
ルートノードであり、この最大値は点(同じセット)を降ろす必要があり
、明らかに有します。
最大の和を取得し、再びピットイン 、最大と同様、その都度、 現在のよう 、次にバックトラック、負の無限大に等しいです。それは重ならないように保証することができます。
#include<bits/stdc++.h>
#define FOR(i,l,r) for(int i=l;i<=r;i++)
#define sf(x) scanf("%d",&x)
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 405000;
int n,A[maxn];
vector<int>G[maxn];
ll dp[maxn],ans=-inf,k;
void dfs1(int u,int f){
dp[u]=A[u];
for(auto v:G[u]){
if(v==f)continue;
dfs1(v,u);
dp[u]+=max(dp[v],1ll*0);
}
ans=max(ans,dp[u]);
}
void dfs2(int u,int f){
dp[u]=A[u];
for(auto v:G[u]){
if(v==f)continue;
dfs2(v,u);
dp[u]+=max(dp[v],1ll*0);
}
if(dp[u]==ans){
k++;
dp[u]=-inf;
}
}
int main(){
cin>>n;
FOR(i,1,n)dp[i]=-inf;
FOR(i,1,n)scanf("%d",&A[i]);
FOR(i,1,n-1){
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs1(1,-1);
dfs2(1,-1);
cout<<ans*k<<" "<<k<<endl;
}