地址:http://codeforces.com/contest/1088/problem/E
思路:求选 k 个联通块中所有点的权值总和 sum 与联通块个数 k 的比值的最大值,多解时应使联通块的数量尽可能地多。
那么可以先DFS一遍求出单个连通块的最大权值Max,那么然后就只有找连通块权值==Max的个数即可,在DFS找的过程中,若找到一个,那么应该将其清0,防止其对父节点的影响。
Code:
#include<iostream>
#include<vector>
using namespace std;
typedef long long LL;
const int MAX_N=3e5+5;
int n,m;
int a[MAX_N];
LL Max;
vector<int> e[MAX_N];
LL DFS(int u,int pre,bool boo);
int main()
{
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;++i)
cin>>a[i];
int u,v;
for(int i=1;i<n;++i)
{
cin>>u>>v;
e[u].push_back(v);
e[v].push_back(u);
}
Max=-1e9-5;
DFS(1,0,0);
DFS(1,0,1);
cout<<Max*m<<" "<<m<<endl;
return 0;
}
LL DFS(int u,int pre,bool boo)
{
LL Sum=a[u];
for(auto c:e[u])
if(c!=pre) Sum=max(Sum,Sum+DFS(c,u,boo));
if(!boo) Max=max(Max,Sum);
else if(Sum==Max) ++m,Sum=0;
return Sum;
}