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+5;
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=0;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=1;i<=n;i++) {
            scanf("%d",&a[i]);
            E[i].clear();
        }
        for(int i=1;i<n;i++) {
            int u,v; scanf("%d%d",&u,&v);
            E[u].push_back(v), E[v].push_back(u);
        }
        ans=-INF; k=0;
        dfs(1,0,1), dfs(1,0,0);
        // 1时搜出最大值 0时搜出不相互覆盖的最大值的个数
        printf("%I64d %d\n",ans*(LL)k,k);
    }

    return 0;
}

  

原文地址:https://www.cnblogs.com/zquzjx/p/10090202.html

时间: 2024-11-12 21:58:43

Codeforces Round #525 E - Ehab and a component choosing problem的相关文章

cfE. Ehab and a component choosing problem(贪心)

题意 题目链接 给出一棵树,每个节点有权值,选出\(k\)个联通块,最大化 \[\frac{\sum_{i \in S} a_i}{k}\] Sol 结论:选出的\(k\)个联通块的大小是一样的且都等于最大联通块的大小 证明:因为我们是在保证分数最大的情况下才去最大化\(k\),一个很经典的结论是单独选择一个权值最大的联通块得到的分数一定是最大的,然后我们这时我们才去考虑最大化\(k\) 那么思路就很清晰了,先一遍dfs dp出最大联通块,然后再一遍dfs从下往上删就行了 #include<bi

cf1088E Ehab and a component choosing problem (树形dp)

题意(考试时看错了对着样例wa了好久..):从树上选k个连通块,使得权值的平均值最大的基础上,选的块数最多 如果不考虑块数最多的限制,肯定是只选一个权值最大的块是最好的 然后只要看这个权值最大的块有多少个不相交的就可以了 做法就是,在dp的时候,一旦找到了和最大权值相等的块,直接统计答案,然后把这一块的权值改成-inf 1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define CLR(a,x) memset(a,x

Codeforces Round #525 (Div. 2)

Codeforces Round #525 (Div. 2) glhf T1: 题意:求两个数\(a,b\)使\(1<=a,b<=n\),\(a\)%\(b==0\),\(a/b<n\),\(a*b>n\) \(n<=100\) 当时直接打了暴力 #include<map> #include<queue> #include<cmath> #include<bitset> #include<cstdio> #inclu

Codeforces Round #525 (Div. 2)A. Ehab and another construction problem

A. Ehab and another construction problem 题目链接:https://codeforc.es/contest/1088/problem/A 题意: 给出一个x,找出这样的a,b满足:1<=a,b<=x,并且a%b=0,a/b<x,a*b>x. 题解: 赛后发现,除开x=1的情况,其它情况a=b=x就可以满足条件了... 但还是附上比赛时候的代码吧... #include <bits/stdc++.h> using namespace

Codeforces Round #410 (Div. 2)C. Mike and gcd problem(数论)

传送门 Description Mike has a sequence A = [a1, a2, ..., an] of length n. He considers the sequence B = [b1, b2, ..., bn] beautiful if the gcd of all its elements is bigger than 1, i.e. . Mike wants to change his sequence in order to make it beautiful.

Codeforces Round #343 (Div. 2) B. Far Relative’s Problem

题意:n个人,在规定时间范围内,找到最多有多少对男女能一起出面. 思路:ans=max(2*min(一天中有多少个人能出面)) 1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cstdio> 6 #include<set> 7 #include<map> 8 #include<ve

Codeforces Round #320 (Div. 1) [Bayan Thanks-Round] A A Problem about Polyline

题目中给出的函数具有周期性,总可以移动到第一个周期内,当然,a<b则无解. 假设移动后在上升的那段,则有a-2*x*n=b,注意限制条件x≥b,n是整数,则n≤(a-b)/(2*b).满足条件的x≥(a-b)/(2*n) 假设在下降的那段,2*x-(a-2*x*n)=b,n+1≤(a+b)/(2*b),x≥(a+b)/(2*(n+1)) 两者取最小值 #include<bits/stdc++.h> using namespace std; int main() { int a,b; sc

Codeforces Round #361 (Div. 2) E. Mike and Geometry Problem

题目链接:传送门 题目大意:给你n个区间,求任意k个区间交所包含点的数目之和. 题目思路:将n个区间都离散化掉,然后对于一个覆盖的区间,如果覆盖数cnt>=k,则数目应该加上 区间长度*(cnt与k的组合数) ans=ans+(len*C(cnt,k))%mod; #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorith

Educational Codeforces Round 80 (Rated for Div. 2) D. Minimax Problem

D. Minimax Problem time limit per test 5 seconds memory limit per test 512 megabytes input standard input output standard output You are given nn arrays a1a1, a2a2, ..., anan; each array consists of exactly mm integers. We denote the yy-th element of