• 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

    题意:

    给出一个数,找出k个连通块,使得连通块里面点的和除以k最大。当选择不同数量的连通块有相同的最大值时,要求输出k最大的情况。

    题解:

    由于这个不等式average(x1,x2,x3...xn)<=max(x1,x2,...xn)成立(当且仅当x1=x2=...xn时,等号成立),而题目所求正好是连通块里面点和的平均值。

    我们要让average(x1,x2,x3...xn)最大,一是尽量满足等号成立的条件,二是尽量让连通块里面的权和最大。

    由于题目中要求k尽量最大。

    所以我们可以进行两次dfs,第一次找出最大的连通块,第二次看看有多少个连通块等于之前找到的最大值,并且更新k的值以及所有点的权值和。

    求最大连通块的时候用到最大连续子段和的技巧,负数就舍去,当儿子为正数才更新值。

    代码如下:

    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #define INF 9999999999
    using namespace std;
    
    const int N = 3e5+5 ;
    typedef long long ll;
    int a[N],head[N],vis[N];
    int n,tot,k;
    struct Edge{
        int u,v,next;
    }e[N<<1];
    ll dp[N];
    ll ans=-INF;
    void adde(int u,int v){
        e[++tot].u=u;e[tot].v=v;e[tot].next=head[u];head[u]=tot;
        e[++tot].u=v;e[tot].v=u;e[tot].next=head[v];head[v]=tot;
    }
    void dfs(int node,int f){
        dp[node]=a[node];
        vis[node]=1;
        for(int i=head[node];i!=-1;i=e[i].next){
            int v=e[i].v;
            if(!vis[v]){
                vis[v]=1;
                dfs(v,f);
                if(dp[v]>0) dp[node]+=dp[v];
            }
        }
        if(!f) ans=max(ans,dp[node]);
        else{
            if(dp[node]==ans){
                k++;
                dp[node]=0;
            }
        }
    }
    int main(){
        scanf("%d",&n);
        memset(head,-1,sizeof(head));
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1,u,v;i<=n-1;i++){
            scanf("%d%d",&u,&v);
            adde(u,v);
        }
        dfs(1,0);
        memset(vis,0,sizeof(vis));
        dfs(1,1);
        cout<<ans*k<<" "<<k<<endl;
        return 0;
    }
  • 相关阅读:
    【NOIP】提高组2015 神奇的幻方
    【BZOJ】1087: [SCOI2005]互不侵犯King
    【NOIP】提高组2005 过河
    【NOIP】提高组2012 借教室
    【vijos】P1083 小白逛公园
    【vijos】P1659 河蟹王国
    【vijos】P1448 校门外的树
    【vijos】P1066 弱弱的战壕
    【TYVJ】P1039 忠诚2
    【TYVJ】P1038 忠诚
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10079891.html
Copyright © 2020-2023  润新知