题意:

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

这个bi值和ci值的范围是[0,1]

题解:

对于一个节点,如果它的bi==ci,那么我们就不用管它(因为你改变它的值,那么肯定之后还要花费成本再改回来,增加了成本)。那么我们首先找出来一共有多少个节点bi!=ci ,然后总权值肯定是

num1*a1+num2*a2...+numn*an

numi表示从节点 i 的子树中选择任意numi个节点

那么肯定是尽可能在ai的值越小的子树上尽量增加numi的数量,这样总权值肯定最小

cnt0[i]:以i节点为树根的子树,在bi!=ci,bi等于0的数量

cnt1[i]:以i节点为树根的子树,在bi!=ci,bi等于1的数量

那么我们就从树根开始dfs,并且维护一个ai最小值,在dfs过程中记录一下i这个节点的所有子节点上bi!=ci的数量(如果bi!=ci,还要记录一下i这个点的bi值),如果ai等于我们维护的那个ai最小值,那就对这个节点

的2*min(cnt0[i],cnt1[i])个节点进行排序。然后让cnt1[i]和cnt0[i]都减去min(cnt0[i],cnt1[i])

最后判断一下cnt1[1]和cnt0[1]是否为0,等于0就代表所有节点bi都等于ci,否则输出-1

代码:

#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string>
#include<queue>
#include<deque>
#include<string.h>
#include<map>
#include <iostream>
#include <math.h>
#define Mem(a,b) memset(a,b,sizeof(a))
const double II = acos(-1);
const double PP = (II*1.0)/(180.00);
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=2e5+10;
ll a[maxn],b[maxn],c[maxn],cnt0[maxn],cnt1[maxn],sum;
vector<ll>w[maxn];
void dfs(ll x,ll fa,ll minn)
{
minn=min(minn,a[x]);
for(ll i=0;i<w[x].size();++i)
{
ll now=w[x][i];
if(now!=fa)
{
dfs(now,x,minn);
cnt0[x]+=cnt0[now];
cnt1[x]+=cnt1[now];
}
}
if(b[x]!=c[x])
{
if(b[x])
cnt1[x]++;
else cnt0[x]++;
}
if(minn==a[x])
{
ll ans=min(cnt0[x],cnt1[x]);
ans*=2;
//printf("%d %d****\n",ans,a[x]);
sum=sum+ans*a[x];
ans/=2;
cnt0[x]-=ans;
cnt1[x]-=ans;
}
}
int main()
{
ll n;
sum=0;
scanf("%I64d",&n);
for(ll i=1;i<=n;++i)
{
scanf("%I64d%I64d%I64d",&a[i],&b[i],&c[i]);
}
for(ll i=1;i<n;++i)
{
ll u,v;
scanf("%I64d%I64d",&u,&v);
w[u].push_back(v);
w[v].push_back(u);
}
dfs(1,0,INF);
if(cnt1[1] || cnt0[1])
{
printf("-1\n");
}
else printf("%I64d\n",sum);
}

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

  1. Codeforces Round #646 (Div. 2) E. Tree Shuffling(树上dp)

    题目链接:https://codeforces.com/contest/1363/problem/E 题意 有一棵 $n$ 个结点,根为结点 $1$ 的树,每个结点有一个选取代价 $a_i$,当前 $ ...

  2. Codeforces Round #316 (Div. 2) D. Tree Requests dfs序

    D. Tree Requests time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

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

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

  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 #353 (Div. 2) D. Tree Construction 二叉搜索树

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

  6. 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 ...

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

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

  8. 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 ...

  9. Codeforces Round #527 (Div. 3) F. Tree with Maximum Cost 【DFS换根 || 树形dp】

    传送门:http://codeforces.com/contest/1092/problem/F F. Tree with Maximum Cost time limit per test 2 sec ...

随机推荐

  1. MySQL多版本并发控制——MVCC机制分析

    MVCC,即多版本并发控制(Multi-Version Concurrency Control)指的是,通过版本链维护一个数据的多个版本,使得读写操作没有冲突,可保证不同事务读写.写读操作并发执行,提 ...

  2. cmd的终结工具cmder

    常用快捷键 win+alt+t  打开任务设置窗口 win+alt+k 打开快捷键设置窗口 自定义屏幕分割窗口快捷键: ctl+shift+s 水平按50%比例分割 ctl+shift+v 垂直按50 ...

  3. Goby资产扫描工具安装及报错处理

    官网: https://cn.gobies.org/index.html 产品介绍: 帮企业梳理资产暴露攻击面,新一代网络安全技术,通过为目标建立完整的资产数据库,实现快速的安全应急. 已有功能: 扫 ...

  4. window安装nvm

    先说一下背景,最近做的两个项目一个是祖传angularjs1.X版本另一个是react hooks结合tailwindcss,前者angularjs的node版本比较低,而tailwindcss的no ...

  5. REUSE_ALV_FIELDCATALOG_MERGE函数

    今天使用REUSE_ALV_FIELDCATALOG_MERGE函数,就是获取不到fieldcat, 搞了半天才发现,原来参数要全部大写才行!!小写字符就是获取不到,唉,悲哀...

  6. Python 中 lru_cache 的使用和实现

    在计算机软件领域,缓存(Cache)指的是将部分数据存储在内存中,以便下次能够更快地访问这些数据,这也是一个典型的用空间换时间的例子.一般用于缓存的内存空间是固定的,当有更多的数据需要缓存的时候,需要 ...

  7. 前端知识(一)02 初识 Node.js-谷粒学院

    目录 初识Node.js 一.Node.js的概念 1.JavaScript引擎 2.什么是Node.js 3.Node.js有什么用 二.BFF 1.BFF 解决什么问题 2.BFF是什么 三.安装 ...

  8. [APUE] 进程环境

    APUE 一书的第七章学习笔记. 进程终止 有 8 种方式可以使得进程终止,5 种为正常方式: Return from main Calling exit() Calling _exit or _Ex ...

  9. 转 Fiddler4 手机抓包

    Fiddler4 手机抓包  文章转自:https://www.cnblogs.com/zhengna/p/10876954.html 1.要对计算机Fiddler进行配置,允许远程计算机连接. 2. ...

  10. java虚拟机入门(一)-jvm基础

    转行学java之前,总是听着大佬们说着java像个渣男一样可以跨平台,一次编译到处运行,瞬间,我就坚定了学java的信念,哎呀妈呀,得劲.真的学java之后,好像渣男也不是那么好学的,尤其这货的必杀技 ...