Codeforces Round #525 (Div. 2)-E. Ehab and a component choosing problem

地址: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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值