加权重心(换根DP)

题目

换根DP,手推一下即可。

代码如下:

cpp 复制代码
#include <bits/stdc++.h>
#define int long long
#define MAXN 100010
using namespace std;

int N, A, B, L, C, minn = 0x3f3f3f3f3f3f3f3f, size[MAXN], dp[MAXN];
vector<pair<int, int>> tree[MAXN];

void dfs1(int u, int pa) {
    size[u] = tree[u][0].first;
    for (int i = 1; i < (int) tree[u].size(); i++) {
        int v = tree[u][i].first, w = tree[u][i].second;
        if (v == pa)
            continue;
        dfs1(v, u);
        size[u] += size[v];
        dp[u] += dp[v] + size[v] * w;
    }
}

void dfs(int u, int pa) {
    for (int i = 1; i < (int) tree[u].size(); i++) {
        int v = tree[u][i].first, w = tree[u][i].second;
        if (v == pa)
            continue;
        dp[v] = dp[u] - size[v] * w + (size[1] - size[v]) * w;
        dfs(v, u);
    }
}

signed main () {
    scanf("%lld", &N);
    for (int i = 1; i <= N; i++) {
        scanf("%lld", &C);
        tree[i].push_back({C, 0});
    }
    for (int i = 1; i < N; i ++) {
        scanf("%lld%lld%lld", &A, &B, &L);
        tree[A].push_back({B, L});
        tree[B].push_back({A, L});
    }
    dfs1(1, 0);
    dfs(1, 0);
    for (int i = 1; i <= N; i++) {
        minn = min(minn, dp[i]);
    }
    printf("%lld", minn);
}
相关推荐
旖旎夜光1 小时前
【C++ 基础入门】C++ 多态(中):虚函数表、多态原理与动静绑定
开发语言·c++·笔记·学习
NEFU_Jyj1 小时前
贝尔数(组合数学)
算法
希和20272 小时前
C语言程序设计题|有序数组插入数字冒泡排序
c语言·数据结构·算法
旖旎夜光2 小时前
【C++ 基础入门】C++多态(下):单/多继承虚表、多态补充与 21 道高频题
开发语言·c++·笔记·学习
Pniubi2 小时前
力扣73 矩阵置零
算法·leetcode·矩阵
apcipot_rain12 小时前
C++转Java日记(03)
java·开发语言·c++
布莱克60512 小时前
C++ 中 map 的 insert 与 emplace:key 已存在时会覆盖吗?
开发语言·数据结构·c++·算法·map
xys_67812 小时前
深挖C++:类和对象(中)
开发语言·c++
D e re k ZH15 小时前
C++ 系统学习手记:从语法细节到工程实践
开发语言·数据结构·c++·算法