Codeforces Round #525 E - Ehab and a component choosing problem
题目大意:
在一棵树中 选出k个联通块 使得 这k个联通块的点权总和 / k 最大
并且这k个联通块不相互覆盖(即一个点只能属于一个联通块)
如果有多种方案,找到k最大的那种
给定n 有n个点
给定n个点的点权(点权可能出现负数)
给定这个树的n-1条边
当将所有点分成联通块后,比较各个强联通块的点权总和,绝对存在最大值,而点权总和=最大值的也可能有多个
此时 若选择了所有点权总和等于最大值的联通块,那么 /k 之后得到的 ans=这个最大值
假设继续选择次大值,那么此时 res = (ans*k+次大值 ) / (k+1) ,显然这个res会因次大值而 res<ans,即选择次大值无法使得答案更优
所以若我们找到了最大值,最优的选择就是 直接选择所有点权总和等于最大值的联通块,无论点权总和最大值为正负,都是这样
不过由于点权存在负数,若要最大化点权总和,显然不能将点权为负数的点并做联通块
所以当u点要将v点并做联通块时,应先考虑v点的权值是否小于0,若小于0则不并
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int N=3e5+;
int n,k,a[N];
LL ans,fe[N];
vector <int> E[N];
void dfs(int u,int fa,int op) {
fe[u]=(LL)a[u];
for(int i=;i<E[u].size();i++) {
int v=E[u][i];
if(v==fa) continue;
dfs(v,u,op);
fe[u]+=max(fe[v],0LL);
}
if(op) ans=max(ans,fe[u]);
else if(fe[u]==ans) k++, fe[u]=0LL;
// 搜索最大值个数时 除记录个数外 将fe[u]置零
// 防止父亲(或父亲的父亲...)因加上该值又得到最大值 则发生覆盖
}
int main()
{
while(~scanf("%d",&n)) {
for(int i=;i<=n;i++) {
scanf("%d",&a[i]);
E[i].clear();
}
for(int i=;i<n;i++) {
int u,v; scanf("%d%d",&u,&v);
E[u].push_back(v), E[v].push_back(u);
}
ans=-INF; k=;
dfs(,,), dfs(,,);
// 1时搜出最大值 0时搜出不相互覆盖的最大值的个数
printf("%I64d %d\n",ans*(LL)k,k);
} return ;
}
Codeforces Round #525 E - Ehab and a component choosing problem的更多相关文章
- Codeforces Round #525 D - Ehab and another another xor problem /// 构造
题目大意: 本题有两个隐藏起来的a b(1<=a,b<=1e30) 每次可 printf("? %d %d\n",c,d); 表示询问 a^c 与 b^d 的相对大小 ...
- Codeforces Round #525 (Div. 2)E. Ehab and a component choosing problem
E. Ehab and a component choosing problem 题目链接:https://codeforces.com/contest/1088/problem/E 题意: 给出一个 ...
- Codeforces 1088E Ehab and a component choosing problem
Ehab and a component choosing problem 如果有多个连接件那么这几个连接件一定是一样大的, 所以我们先找到值最大的连通块这个肯定是分数的答案. dp[ i ]表示对于 ...
- Codeforces Round #525 (Div. 2) E. Ehab and a component choosing problem 数学
题意:给出树 求最大的sigma(a)/k k是选取的联通快个数 联通快不相交 思路: 这题和1个序列求最大的连续a 的平均值 这里先要满足最大平均值 而首先要满足最大 也就是一个数的时候可 ...
- cf1088E Ehab and a component choosing problem (树形dp)
题意(考试时看错了对着样例wa了好久..):从树上选k个连通块,使得权值的平均值最大的基础上,选的块数最多 如果不考虑块数最多的限制,肯定是只选一个权值最大的块是最好的 然后只要看这个权值最大的块有多 ...
- 【数学/贪心/DP】【CF1088E】 Ehab and a component choosing problem
Description 给定一棵 \(n\) 个节点的树,点有点权 \(a_u\),可能为负.现在请你在树上找出 \(k~(1~\leq~k~\leq~n)\) 个不相交集合,使得每个集合中的每对点都 ...
- cfE. Ehab and a component choosing problem(贪心)
题意 题目链接 给出一棵树,每个节点有权值,选出\(k\)个联通块,最大化 \[\frac{\sum_{i \in S} a_i}{k}\] Sol 结论:选出的\(k\)个联通块的大小是一样的且都等 ...
- Codeforces Round #525 (Div. 2) Solution
A. Ehab and another construction problem Water. #include <bits/stdc++.h> using namespace std; ...
- CodeForces Round 525
A:Ehab and another construction problem #include<bits/stdc++.h> using namespace std; #define F ...
随机推荐
- CF D. Walking Between Houses (贪心)
题意: 现在有n个房子排成一列,编号为1~n,起初你在第1个房子里,现在你要进行k次移动,每次移动一都可以从一个房子i移动到另外一个其他的房子j里(i != j),移动的距离为|j - i|.问你进过 ...
- 其它课程中的python---5、Pandas处理数据和读取数据
其它课程中的python---5.Pandas处理数据和读取数据 一.总结 一句话总结: 记常用和特例:慢慢慢慢的就熟了,不用太着急,慢慢来 库的使用都很简单:就是库的常用函数就这几个,后面用的时候学 ...
- java求两个数中的大数
java求两个数中的大数 java中的max函数在Math中 应用如下: int a=34: int b=45: int ans=Math.max(34,45); 那么ans的值就是45.
- (12)centos7 环境变量配置
export 一个变量的设置一般只在当前环境有效,export命令可以用于传递一个或多个变量的值到任何后续脚本.export可新增.修改或删除环境变量,供后续执行的程序使用.export的效力限于该次 ...
- java.lang.Object错误
java.lang.Object错误 项目遇到一个错误 因为构建路径不完整..... 主要是因为缺少JDK(java.lang.Object来自那里),或者是JDK错误. 右击项目-->属性-- ...
- webdriver使用已打开过的chrome
基本功能: 执行脚本a,打开一个chrome,脚本a执行完成,chrome未关闭. 执行脚本b,继续使用a打开的chrome,不新启浏览器. 附加: 如果已打开的chrome未关闭,则在chrome中 ...
- Java8 时间调节器
TemporalAdjuster 是做日期数学计算.例如,要获得“本月第二个星期六”或“下周二”. 让我们来看看他们的操作. 选择使用任何编辑器创建以下java程序在 C:/> JAVA Jav ...
- 高级UI晋升之View渲染机制(二)
更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 优化性能一般从渲染,运算与内存,电量三个方面进行,今天开始说聊一聊Android ...
- Pandas之read_excel()和to_excel()函数解析
read_excel() 加载函数为read_excel(),其具体参数如下. read_excel(io, sheetname=0, header=0, skiprows=None, skip_fo ...
- JAVA集合--Iterator接口
本文首发于cartoon的博客 转载请注明出处:https://cartoonyu.github.io/cartoon-blog 上一篇文章中我在集合元素的遍历中已经有涉及到I ...