我是题面原题地址

很简单的一道贪心题

首先,先想想怎么判断是否合法

题目中说,a是自然数,那么子节点的s明显是不能比父节点大的,如果比父节点大,不合法!

所有深度为偶数的点的s被删除了,也只有深度为偶数的点被删除了,所以如果深度为奇数的点被删除了,或者有深度为偶数的点没有被删除,不合法!

所有不合法的情况我们已经判断完了,下面考虑如何使权值和最小

对于奇数层的点我们肯定是无法影响了,只有通过控制偶数层的点的权值才能影响总的权值和,而且只能影响自己和自己子节点的权值

我们从简单的入手,对于偶数层叶子结点,我们直接让它的\(s\)等于父节点的\(s\)即可,这样\(a\)为\(0\),合法且最优

对于有一个子节点的偶数层节点,取值在\([s_{fa},s_{son}]\)中任意取值,总的权值和都是不变的。

简单证明一下,就是\(a_{son}=s_{son}-s_v,a_{v}=s_v-s_{fa},a_v+a_{son}=s_{son}-s_{fa}\),而两个\(s\)都是已知的,所以这里的s爱取啥取啥,只要合法就行

那么对于子节点大于1的偶数层节点我们怎么处理呢,我们设子节点的权值不全相同

那么\(a_v=s_v-s_{fa},\sum a_{son}=\sum (s_{son}-s_v)\)

总的和就是\(\sum(s_{son}-s_v)+s_v-s_{fa}\)

显然,当\(s_v\)越小时,这个式子的值也就越小,同时我们还要保证合法,所以\(s_v\)我们就取最小的\(s_{son}\)

为了程序的简练,我们将三种情况合并,简述为

若存在子节点则为最小的\(s_{son}\),否则为\(s_{fa}\)

由于数据范围不小,记得开long long

就是这么简单,下面上代码,由于讲的已经很清楚了,代码就不加注释了

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cctype>
#ifdef ONLINE_JUDGE
#define puts(o) puts("I AK IOI\n")
#endif
#define ll long long
#define gc getchar
#define maxn 100005
using namespace std; inline ll read(){
ll a=0;int f=0;char p=gc();
while(!isdigit(p)){f|=p=='-';p=gc();}
while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=gc();}
return f?-a:a;
}int n,ans;ll sum; struct ahaha{
int to,next;
}e[maxn];int tot,head[maxn];
inline void add(int u,int v){
e[tot]={v,head[u]};head[u]=tot++;
} int f[maxn],dep[maxn];ll s[maxn],s1[maxn];
void dfs(int u,int fa){
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(~s[v]){
if((dep[v]&1)^1){ans=1;return;}
}
else{
if(dep[v]&1){ans=1;return;}
s[v]=(s1[v]==1000000001?s[u]:s1[v]);
}
if(s[v]<s[u]){ans=1;return;}
sum+=s[v]-s[u];
dfs(v,u);if(ans)return;
}
}
ll dfs(int u){
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
dep[v]=dep[u]+1;
s1[u]=min(s1[u],dfs(v));
}
return s[u];
} int main(){memset(head,-1,sizeof head);
n=read();dep[1]=1;
for(int i=2;i<=n;++i)
add(read(),i);
for(int i=1;i<=n;++i){
s[i]=read();
s1[i]=1000000001;
}
sum+=s[1];dfs(1);dfs(1,-1);
if(ans)
puts("-1");
else
printf("%I64d\n",sum);
return 0;
}

CF530D sum in the tree的更多相关文章

  1. Codeforces Round #530 (Div. 2):D. Sum in the tree (题解)

    D. Sum in the tree 题目链接:https://codeforces.com/contest/1099/problem/D 题意: 给出一棵树,以及每个点的si,这里的si代表从i号结 ...

  2. CF-1099 D. Sum in the tree

    CF-1099 D. Sum in the tree 题意:结点序号为 1~n 的一个有根树,根序号为1,每个点有一个权值a[i], 然后定义一s[i]表示从根节点到 结点序号为i的结点的路途上所经过 ...

  3. Codeforces Round #530 (Div. 2) D. Sum in the tree 树上贪心

    D. Sum in the tree 题意 给出一颗树,奇数层数的点有值,值代表从1到该点的简单路的权值的和,偶数层数的点权值被擦去了 问所有节点的和的最小可能是多少 思路 对于每一个-1(也就是值未 ...

  4. Codeforces Round #530 (Div. 1) 1098A Sum in the tree

    A. Sum in the tree Mitya has a rooted tree with nn vertices indexed from 11 to nn, where the root ha ...

  5. codeforces #530 D(Sum in the tree) (树上贪心)

    Mitya has a rooted tree with nn vertices indexed from 11 to nn, where the root has index 11. Each ve ...

  6. D. Sum in the tree(树形+贪心)

    题目链接;http://codeforces.com/contest/1099/problem/D 题目大意:给出一棵树,每个节点到根节点的路径上经过的所有点的权值之和,其深度为偶数的节点的信息全部擦 ...

  7. Codeforces1099D.Sum in the tree(贪心)

    题目链接:传送门 思路: 一个节点放的数越大,那么以它为根的子树的节点权值之和就越小. 所以我们要在合法的范围内,使偶数层节点的权值尽可能地大.也就是说,令它的权值是子节点的最小值,这样保证了它的子节 ...

  8. 【LeetCode OJ】Binary Tree Maximum Path Sum

    Problem Link: http://oj.leetcode.com/problems/binary-tree-maximum-path-sum/ For any path P in a bina ...

  9. [LeetCode] Path Sum II 二叉树路径之和之二

    Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given su ...

随机推荐

  1. Java——RMI

    之前分布式系统调用用的是比较老的EJB,当时还是作为服务调用方,去调用别的系统的服务.最近发现新公司里面,用的是RMI,查了下发现EJB的底层实现就是RMI,也算是熟悉了... 一,使用JDK 中的R ...

  2. Python运维三十六式:用Python写一个简单的监控系统

    市面上有很多开源的监控系统:Cacti.Nagios.Zabbix.感觉都不符合我的需求,为什么不自己做一个呢? 用Python两个小时徒手撸了一个简易的监控系统,给大家分享一下,希望能对大家有所启发 ...

  3. js中对象转化成字符串、数字或布尔值的转化规则

    js中对象可以转化成 字符串.数字.布尔值 一.对象转化成字符串: 规则: 1.如果对象有toString方法,则调用该方法,并返回相应的结果:(代码通常会执行到这,因为在所有对象中都有toStrin ...

  4. 原生android(二)——认识activity

    一.activity的生命周期 1.onCreate():在活动第一次被创建的时候调用,用来完成活动的初始化操作,如加载布局.绑定事件等 2.onStart():在活动由不可见变为可见时被调用 3.o ...

  5. Selenium2+python自动化-操作浏览器基本方法

    前言 从这篇开始,正式学习selenium的webdriver框架.我们平常说的 selenium自动化,其实它并不是类似于QTP之类的有GUI界面的可视化工具,我们要学的是webdriver框架的A ...

  6. [Ubuntu] <uptime>命令

    uptime 命令 就是查看系统启动时间的,前几个大家应该都很熟悉:当前时间.系统启动时间.正在登陆的用户数 最后的三个数字,分别代表过去 1分钟  5分钟  15分钟  的平均负载(Load Ave ...

  7. dp算法之硬币找零问题

    题目:硬币找零 题目介绍:现在有面值1.3.5元三种硬币无限个,问组成n元的硬币的最小数目? 分析:现在假设n=10,画出状态分布图: 硬币编号 硬币面值p 1 1 2 3 3 5 编号i/n总数j ...

  8. Appstate的几种状态及在android 和ios触发

    AppState能告诉你当前应用是在前台还是在后台,或者处于切换应用的状态,并且能在状态变化的时候通知你. AppState 通常在处理推送通知的时候用来决定内容和对应的行为 一: App State ...

  9. 爬虫:Scrapy12 - Stats Collection

    Scrapy 提供了方便的收集数据的机制.数据以 key/value 方式存储,值大多是计数值.该机制叫做数据收集器(Stats Collector),可以通过 Crawler API 的属性 sta ...

  10. Split the Number(思维)

    You are given an integer x. Your task is to split the number x into exactly n strictly positive inte ...