传送门:https://codeforces.com/contest/1088/problem/E
题意:给一棵树,找不超过n个联通块,彼此不相交,且权值总和除以联通块数量最大,如果有多解,要求联通块数量最多。
题解:根据平均数可知,答案就是找出来有几个权值和最大的联通块,注意不要彼此覆盖。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int head[300005],cnt,n,k,a[300005];
ll dp[300005];
ll cnts,ans=-10000000000000000LL;
struct node{
int to,nex;
}edge[600005];
void add(int u,int v){
edge[cnt].to=v;
edge[cnt].nex=head[u];
head[u]=cnt++;
}
void dfs(int t,int f){
dp[t]=a[t];
for(int i=head[t];~i;i=edge[i].nex){
int v=edge[i].to;
if(v==f)continue;
dfs(v,t);
dp[t]=max(dp[t],dp[t]+dp[v]);
}
ans=max(ans,dp[t]);
}
ll dfss(int t,int f){
dp[t]=a[t];
for(int i=head[t];~i;i=edge[i].nex){
int v=edge[i].to;
if(v==f)continue;
dp[t]=max(dp[t],dp[t]+dfss(v,t));
}
if(dp[t]==ans){
cnts++;
return 0;
}
return dp[t];
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
memset(head,-1,sizeof(head));
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs(1,1);
dfss(1,1);
printf("%lld %lld\n",cnts*ans,cnts);
return 0;
}