加权重心(换根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 小时前
【python因果库实战26】逆概率加权模型1
开发语言·python·算法·leetcode
2401_840105201 小时前
题解: [GESP202409 八级] 美丽路径
数据结构·c++·算法·动态规划
今儿敲了吗2 小时前
链表篇(五)——链表中间结点
数据结构·笔记·算法·链表
码农的神经元2 小时前
2026 年数维杯A 题:抱轨式磁浮列车的悬浮电磁铁故障检测问题
人工智能·算法·数学建模
YYYing.2 小时前
【C++项目之高并发内存池 (三)】万字解析CentralCache与PageCache的初步实现
c++·笔记·哈希算法·高并发·c/c++·内存池
小新同学^O^2 小时前
算法学习 --> 快速输入和输出
java·学习·算法
脑子加油站2 小时前
K8S-Ingress资源对象
算法·贪心算法·k8s
Chase_______2 小时前
【算法】LeetCode 1052 & 3679:定长滑动窗口进阶——增益最大化与频率约束贪心
算法·leetcode
天若有情6732 小时前
从零搭建局域网手机遥控电脑网页项目,吃透工程化与架构设计思维
服务器·前端·数据库·算法·开源·node·工程化