zoukankan      html  css  js  c++  java
  • [CF1092F] Tree with Maximum Cost

    Description

    (n) 个节点的树,每个节点有一点权 (a_i)。定义 ( extrm{dist}(x,y))(x)(y) 的边数。选取一点 (v),使 $ sum_{i=1}^{n}a_i cdot extrm{dist}(i ,v)$ 最大

    Solution

    典型换根 dp,设 (1) 号点为根,设 (s[i]) 表示点 (i) 子树中的权值和,(f[i]) 表示 (v=i) 时的答案,首先我们可以通过一次 DFS 算出 (f[1]),同时有转移方程

    [f[q]=f[p]-s[q]+s[1]-s[q]=f[p]+s[1]-2s[q] ]

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 1000005;
    
    vector <int> g[N];
    int n,a[N],dep[N],f[N],s[N],vis[N];
    
    void dfs1(int p) {
        vis[p]=1;
        f[1]+=a[p]*dep[p];
        s[p]=a[p];
        for(int q:g[p]) if(!vis[q]) {
            dep[q]=dep[p]+1;
            dfs1(q);
            s[p]+=s[q];
        }
    }
    
    void dfs2(int p) {
        vis[p]=1;
        for(int q:g[p]) if(!vis[q]) {
            f[q]=f[p]+s[1]-2*s[q];
            dfs2(q);
        }
    }
    
    signed main() {
        ios::sync_with_stdio(false);
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        for(int i=1;i<n;i++) {
            int u,v;
            cin>>u>>v;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        dfs1(1);
        memset(vis,0,sizeof vis);
        dfs2(1);
        cout<<*max_element(f+1,f+n+1);
    }
    
  • 相关阅读:
    FastAdmin 提示框 toastr 改变文字
    FastAdmin 将会员模块升级为基础模块的升级指导
    随笔
    随笔
    c++11 lambda(了解)
    c++11 类型推断
    boost::archive::text_oarchive
    std::ostringstream
    随笔
    随笔1
  • 原文地址:https://www.cnblogs.com/mollnn/p/12952668.html
Copyright © 2011-2022 走看看