zoukankan      html  css  js  c++  java
  • P3574 [POI2014]FAR-FarmCraft (树形DP)

    这题直接贪心显然不可行.

    考虑树形dp,用 (f_i) 表示到 (i) 人后,以 (i) 为根的所有人安装完的最短时间.

    对于一个节点 (u), 假设拜访子节点的顺序为 (v_1,v_2,...,v_m) ,那么得到转移方程.

    [f_u = max(f_v + sumlimits_{j = 1}^{i - 1}sum_j) ]

    其中 (sum_i) 表示拜访完以 (i) 为根的子树的所有人所花的时间,即 ((siz_i -1) *2)

    拜访的顺序考虑贪心

    对于两个相邻整数 (i,j)​ ,必须满足 (f_j + sumlimits_{k =1}^{j-1}sum_k<f_i+ sumlimits_{k=1}^{i-1}sum_k+sum_j)

    ( o f_j+sum_i < f_i+sum_j\ o f_j-sum_j<f_i-sum_i)

    所以只要将 (f_i - sum_i) 从大到小排序即可.

    const int N = 5e5 + 10;
    vector<int>e[N];
    int f[N], a[N], g[N];
    bool cmp(int x, int y) {return g[x] - f[x] > g[y] - f[y];}
    void dfs(int u, int fa) {
        for (int v : e[u]) {
            if (v == fa)continue;
            dfs(v, u);
        }
        sort(e[u].begin(), e[u].end(), cmp);
        if (u != 1) g[u] = a[u];
        for (int v : e[u]) {
            if (v == fa)continue;
            g[u] = max(g[u], g[v] + f[u] + 1);
            f[u] += f[v] + 2;
        }
    }
    int main() {
        cin.tie(nullptr)->sync_with_stdio(false);
        int n; cin >> n;
        for (int i = 1; i <= n; ++i) cin >> a[i];
        for (int i = 1, x, y; i < n; ++i) {
            cin >> x >> y;
            e[x].push_back(y);
            e[y].push_back(x);
        }
        dfs(1, 0);
        cout << max(g[1], f[1] + a[1]);
    }
    

    The desire of his soul is the prophecy of his fate
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    caffe中的前向传播和反向传播
    net_->ForwardBackward()的大致梳理
    caffe Solve函数
    GA求解TSP
    BP网络中的反向传播
    Python模块路径查找
    Jupyter 美化
    不重装anaconda升级base中的Python版本
    查看谷歌浏览器保存在本地的密码
    爬取腾讯视频
  • 原文地址:https://www.cnblogs.com/RioTian/p/15111199.html
Copyright © 2011-2022 走看看