zoukankan      html  css  js  c++  java
  • Codeforces Round #525 E

    题目大意:

    在一棵树中 选出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
    ",ans*(LL)k,k);
        }
    
        return 0;
    }
    View Code

      

  • 相关阅读:
    Android 开发之旅:view的几种布局方式及实践
    递归列举从数组b()中选出某些元素(允许重复)使其和等于num的所有组合
    被感动的感觉
    Table of ASCII Characters
    Export selection of word document as an image file(2)
    ZendStudiov6.0注册机
    windows mobile中求存储空间大小
    微软宣布20号起黑屏警告XP专业版盗版用户
    百度竟价 统计与重定向
    大象Thinking in UML早知道 006 非功能性需求
  • 原文地址:https://www.cnblogs.com/zquzjx/p/10090202.html
Copyright © 2011-2022 走看看