题目链接:https://codeforces.com/contest/1363/problem/E

题意

有一棵 $n$ 个结点,根为结点 $1$ 的树,每个结点有一个选取代价 $a_i$,当前 $b_i$,目标数字 $c_i$ 。每次可以选择以一个结点为根节点的子树中的 $k$ 个结点交换它们的 $b_i$,总代价为 $k \times a_{root}$ ,判断能否把所有结点都变为目标数字以及最小代价。

题解

因为每棵子树都可以被包含进更大的子树中,所以对于每棵子树的根节点,它的最小选取代价可以取它自身和所有可能的父节点的最小值。

计算每棵子树中需要交换的 $0$ 和 $1$ 的个数,用根节点的最小选取代价交换后,多余的 $0$ 或 $1$ 累加至父节点所在的子树即可。

代码

#include <bits/stdc++.h>
using ll = long long;
using namespace std;
const int N = 2e5 + 10; vector<int> G[N];
int a[N], b[N], c[N];
int cnt[N][2];
ll ans; void dfs(int u, int pre) {
if (pre != 0) a[u] = min(a[u], a[pre]);
for (auto v : G[u]) {
if (v != pre) {
dfs(v, u);
cnt[u][0] += cnt[v][0];
cnt[u][1] += cnt[v][1];
}
}
if (b[u] != c[u]) cnt[u][b[u]]++;
int mi = min(cnt[u][0], cnt[u][1]);
ans += 2LL * mi * a[u];
cnt[u][0] -= mi;
cnt[u][1] -= mi;
} int main() {
int n; cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i] >> b[i] >> c[i];
for (int i = 0; i < n - 1; i++) {
int u, v; cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1, 0);
cout << ((cnt[1][0] or cnt[1][1]) ? -1 : ans) << "\n";
}

参考博客:https://www.cnblogs.com/axiomofchoice/p/13022886.html

Codeforces Round #646 (Div. 2) E. Tree Shuffling(树上dp)的更多相关文章

  1. Codeforces Round #646 (Div. 2) E. Tree Shuffling dfs

    题意: 给你n个节点,这n个节点构成了一颗以1为树根的树.每一个节点有一个初始值bi,从任意节点 i 的子树中选择任意k个节点,并按他的意愿随机排列这些节点中的数字,从而产生k⋅ai 的成本.对于一个 ...

  2. Codeforces Round #499 (Div. 1) F. Tree

    Codeforces Round #499 (Div. 1) F. Tree 题目链接 \(\rm CodeForces\):https://codeforces.com/contest/1010/p ...

  3. Codeforces Round #367 (Div. 2) C. Hard problem(DP)

    Hard problem 题目链接: http://codeforces.com/contest/706/problem/C Description Vasiliy is fond of solvin ...

  4. Codeforces Round #646 (Div. 2) 题解 (ABCDE)

    目录 A. Odd Selection B. Subsequence Hate C. Game On Leaves D. Guess The Maximums E. Tree Shuffling ht ...

  5. Codeforces Round #426 (Div. 2) D 线段树优化dp

    D. The Bakery time limit per test 2.5 seconds memory limit per test 256 megabytes input standard inp ...

  6. Codeforces Round #353 (Div. 2) D. Tree Construction 二叉搜索树

    题目链接: http://codeforces.com/contest/675/problem/D 题意: 给你一系列点,叫你构造二叉搜索树,并且按输入顺序输出除根节点以外的所有节点的父亲. 题解: ...

  7. Codeforces Round #540 (Div. 3)--1118F1 - Tree Cutting (Easy Version)

    https://codeforces.com/contest/1118/problem/F1 #include<bits/stdc++.h> using namespace std; in ...

  8. Codeforces Round #353 (Div. 2) D. Tree Construction 模拟

    D. Tree Construction 题目连接: http://www.codeforces.com/contest/675/problem/D Description During the pr ...

  9. Codeforces Round #540 (Div. 3) F1. Tree Cutting (Easy Version) 【DFS】

    任意门:http://codeforces.com/contest/1118/problem/F1 F1. Tree Cutting (Easy Version) time limit per tes ...

随机推荐

  1. 区间合并 C++

    #include <iostream> #include <vector> #include <algorithm> using namespace std; ty ...

  2. (二)React Ant Design Pro + .Net5 WebApi:前端环境搭建

    首先,你需要先装一个Nodejs,这是基础哦.如果没有这方面知识的小伙伴可以在园子里搜索cnpm yarn等关键字,内容繁多,此不赘述,参考链接 一. 简介 1. Ant Design Pro v5 ...

  3. MySQL全面瓦解16:存储过程相关

    概述 大多数SQL语句都是针对一个或多个表的单条语句.但并非所有业务都这么简单,经常会有复杂的操作需要多条语句才能完成. 比如用户购买一个商品,要删减库存表,要生成订单数据,要保存支付信息等等,他是一 ...

  4. 更改mysql的密码

    mysql> set password for 'root'@'localhost' =PASSWORD('');Query OK, 0 rows affected (0.17 sec) mys ...

  5. linux中进制转换

    方式一:使用$[]或$(()) 格式为:$[base#number]或$((base#number)),其中base为进制,number为对应进制数. 这种方式输入2进制.16进制等,但只能输出为10 ...

  6. 【linux】系统编程-7-网络编程

    目录 前言 10. 网络编程 10.1 简要网络知识 10.2 IP协议 10.2.1 IP地址编址 10.2.2 特殊IP地址 10.2.1 首限广播地址 10.2.2 直接广播地址 10.2.3 ...

  7. gRPC-go源码(1):连接管理

    1 写在前面 在这个系列的文章中,我们将会从源码的层面学习和理解gRPC. 整个系列的文章的计划大概是这样的:我们会先从客户端开始,沿着调用路径逐步分析到服务端,以模块为粒度进行学习,考虑这个模块是为 ...

  8. Java并发包源码学习系列:阻塞队列BlockingQueue及实现原理分析

    目录 本篇要点 什么是阻塞队列 阻塞队列提供的方法 阻塞队列的七种实现 TransferQueue和BlockingQueue的区别 1.ArrayBlockingQueue 2.LinkedBloc ...

  9. (13)-Python3之--获取当前时间

    1.导入datetime模块 import datetime 2.获取当前日期和时间 import datetime now_time = datetime.datetime.now() print( ...

  10. [Python]编码声明:是coding:utf-8还是coding=utf-8呢

    PEP 263 -- Defining Python Source Code Encodings | Python.org https://www.python.org/dev/peps/pep-02 ...