前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >小码匠的编程江湖【第81式】:树形DP:USACO的奶牛大集会

小码匠的编程江湖【第81式】:树形DP:USACO的奶牛大集会

作者头像
小码匠
发布2023-08-31 18:39:35
2650
发布2023-08-31 18:39:35
举报
文章被收录于专栏:小码匠和老码农

题目描述

Bessie 正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会。当然,她会选择最方便的地点来举办这次集会。

每个奶牛居住在 N 个农场中的一个,这些农场由 N−1 条道路连接,并且从任意一个农场都能够到达另外一个农场。道路 i 连接农场

A_i

B_i

,长度为

L_i

。集会可以在 N 个农场中的任意一个举行。另外,每个牛棚中居住着

C_i

只奶牛。

在选择集会的地点的时候,Bessie 希望最大化方便的程度(也就是最小化不方便程度)。比如选择第 X 个农场作为集会地点,它的不方便程度是其它牛棚中每只奶牛去参加集会所走的路程之和(比如,农场 i 到达农场 X 的距离是 20,那么总路程就是

C_i×20

)。帮助 Bessie 找出最方便的地点来举行大集会。

输入格式

第一行一个整数 N 。

第二到 N+1 行:第 i+1 行有一个整数

C_i

第 N+2 行到 2N 行:第 i+N+1 行为 3 个整数:

A_i,B_i 和 L_i

输出格式

一行一个整数,表示最小的不方便值。

输入输出样例

输入 #1复制

代码语言:javascript
复制
5 
1 
1 
0 
0 
2 
1 3 1 
2 3 2 
3 4 3 
4 5 3

输出 #1复制

代码语言:javascript
复制
15
说明/提示
1≤N≤10^5,1≤A_i≤B_i≤N,0≤C_i,L_i≤10^3

题目

题目原文请移步下面的链接

  • https://www.luogu.com.cn/problem/P2986
    • 参考题解:https://www.luogu.com.cn/problem/solution/P2986
  • 标签:OI动态规划树形DP
代码
代码语言:javascript
复制
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <bitset>
#include <array>

using namespace std;

struct node {
    long long v, to, next;
} g[1000005];

vector<long long> size(1000005);
long long ans = 0x7f7f7f7f7f7f7f7f, dp[1000005], len[1000005], cnt = 0, n, m, s[1000005], head[1000005], k = 0;

void add(int u, int v, long long w) {
    g[++k].v = w;
    g[k].to = v;
    g[k].next = head[u];
    head[u] = k;
}


void dfs(int u, int father) {
    size[u] = s[u];
    for (int i = head[u]; i; i = g[i].next) {
        int v = g[i].to;
        if (v == father) {
            continue;
        }
        dfs(v, u);
        size[u] += size[v];
        len[u] = len[u] + len[v] + size[v] * g[i].v;
    }
}

void dp_dfs(int u, int father) {
    for (int i = head[u]; i; i = g[i].next) {
        int v = g[i].to;
        if (v == father) {
            continue;
        }
        dp[v] = 1LL * dp[u] - size[v] * g[i].v + (cnt - size[v]) * g[i].v;
        ans = min(ans, dp[v]);
        dp_dfs(v, u);
    }
}

void best_coder() {
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> s[i];
        cnt += s[i];
    }

    for (int i = 1; i < n; ++i) {
        int u, v;
        long long w;
        cin >> u >> v >> w;
        add(u, v, w);
        add(v, u, w);
    }
    dfs(1, 0);
    dp[1] = len[1];
    ans = min(ans, dp[1]);
    dp_dfs(1, 0);
    cout << ans * 1LL;
}

void happy_coder() {

}

int main() {
//     提升cin、cout效率
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    // 小码匠
    best_coder();

    // 最优解
    // happy_coder();

    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小码匠和老码农 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 输入格式
    • 输出格式
      • 输入输出样例
        • 说明/提示
        • 题目
          • 代码
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档