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

2023-08-31 18:39:35 浏览数 (1)

题目描述

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;
}

0 人点赞