Codeforces 1099 D. Sum in the tree-构造最小点权和有根树 贪心+DFS(Codeforces Round #530 (Div. 2))
2 seconds
256 megabytes
standard input
standard output
Mitya has a rooted tree with nn vertices indexed from 11 to nn, where the root has index 11. Each vertex vv initially had an integer number av≥0av≥0 written on it. For every vertex vv Mitya has computed svsv: the sum of all values written on the vertices on the path from vertex vv to the root, as well as hvhv — the depth of vertex vv, which denotes the number of vertices on the path from vertex vv to the root. Clearly, s1=a1s1=a1 and h1=1h1=1.
Then Mitya erased all numbers avav, and by accident he also erased all values svsv for vertices with even depth (vertices with even hvhv). Your task is to restore the values avav for every vertex, or determine that Mitya made a mistake. In case there are multiple ways to restore the values, you're required to find one which minimizes the total sum of values avav for all vertices in the tree.
The first line contains one integer nn — the number of vertices in the tree (2≤n≤1052≤n≤105). The following line contains integers p2p2, p3p3, ... pnpn, where pipi stands for the parent of vertex with index ii in the tree (1≤pi<i1≤pi<i). The last line contains integer values s1s1, s2s2, ..., snsn (−1≤sv≤109−1≤sv≤109), where erased values are replaced by −1−1.
Output one integer — the minimum total sum of all values avav in the original tree, or −1−1 if such tree does not exist.
5
1 1 1 1
1 -1 -1 -1 -1
1
5
1 2 3 1
1 -1 2 -1 -1
2
3
1 2
2 -1 1
-1
题意就是给你一个有根树,然后给你每个节点的父亲,然后给你每个节点到根节点的点权之和,然后就是偶数深度的节点的到根节点的点权之和被抹去了,是-1,让你将这个树还原,然后求出所有节点的最小点权之和。
因为是隔一层就断了,所以直接直接给偶数深度节点爸爸赋值他儿子的值中最小的那个,然后,儿子-爸爸的值算出每个点的点权,最后加起来就可以了。如果节点的值是负数,就是不满足条件的,直接-1输出就可以了。我写的时候,wa了好久,搞不清楚为什么,不用开long long吧,我不开会wa,然后就是如果一个节点是直接连接根节点的,他没有儿子,那么我们可以给他赋值为0,我这里写早了,写到dfs出来时每个节点的点权之前了,这样算出来的肯定是不对的,就是直接0-根节点的权值,肯定是错的,当时想的是算完之后再处理这些特殊的点,但是手抖写的时候写挫了,改了就过了。
代码:
//D
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdlib>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=2e5+; struct node{
int to,val,next;
}edge[maxn<<]; int head[maxn<<],dep[maxn],fa[maxn][],cnt;
int dis[maxn]; void add(int x,int y,int v){edge[++cnt].to=y,edge[cnt].val=v,edge[cnt].next=head[x],head[x]=cnt;}//存图 void dfs(int u,int fath)
{
dep[u]=dep[fath]+;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to,w=edge[i].val;
if(v!=fath){
dis[v]=w;
if(dep[u]%==){
dis[u]=min(dis[u],dis[v]);//找子节点的值的最小值
}
}
}
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to,w=edge[i].val;
if(v!=fath){
dfs(v,u);
if(dis[v]!=inf)//如果不是特殊节点
dis[v]=dis[v]-dis[u];//当前点的点权就是自己-爸爸的
}
}
} int a[maxn],b[maxn]; int main()
{
int n;
cin>>n;
for(int i=;i<=n;i++)
cin>>a[i];
for(int i=;i<=n;i++){
cin>>b[i];
if(b[i]==-) b[i]=inf;
}
for(int i=;i<=n;i++){
add(a[i],i,b[i]);
add(i,a[i],b[i]);
}
dis[]=b[];
dfs(,);
for(int i=;i<=n;i++){
if(dis[i]==inf) dis[i]=;//如果是特殊节点,处理完还是没确定值的,就赋值为0
}
// for(int i=1;i<=n;i++)
// cout<<dis[i]<<endl;
ll ans=;
int flag=;
for(int i=;i<=n;i++){
if(dis[i]<){
flag=;break;
}
ans+=dis[i];
}
if(flag==) cout<<ans<<endl;
else cout<<-<<endl;
} /*
10
1 1 1 1 2 3 4 5 1
3 -1 -1 -1 -1 3 3 3 3 -1 3
*/
Codeforces 1099 D. Sum in the tree-构造最小点权和有根树 贪心+DFS(Codeforces Round #530 (Div. 2))的更多相关文章
- 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号结 ...
- Codeforces Round #530 (Div. 2) D. Sum in the tree 树上贪心
D. Sum in the tree 题意 给出一颗树,奇数层数的点有值,值代表从1到该点的简单路的权值的和,偶数层数的点权值被擦去了 问所有节点的和的最小可能是多少 思路 对于每一个-1(也就是值未 ...
- 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 ...
- Codeforces Round #530 (Div. 2) A,B,C,D
A. Snowball 链接:http://codeforces.com/contest/1099/problem/A 思路:模拟 代码: #include<bits/stdc++.h> ...
- Codeforces Round #530 (Div. 1)
A - Sum in the tree 就是贪心选尽量让上面的点权尽量大,那么对于偶数层的点,其到根节点的和即为所有儿子中的最大值. #include<bits/stdc++.h> usi ...
- Codeforces Round #530 (Div. 2) Solution
A. Snowball 签. #include <bits/stdc++.h> using namespace std; ], d[]; int main() { while (scanf ...
- Codeforces Round #530 (Div. 2)
RANK :2252 题数 :3 补题: D - Sum in the tree 思路:贪心 把权值放在祖先节点上 ,预处理 每个节点保存 他与他儿子中 权值最小值即可. 最后会有一些叶子节点依旧为 ...
- Codeforces 1099 C. Postcard-字符串处理(Codeforces Round #530 (Div. 2))
C. Postcard time limit per test 1 second memory limit per test 256 megabytes input standard input ou ...
- Codeforces 1099 B. Squares and Segments-思维(Codeforces Round #530 (Div. 2))
B. Squares and Segments time limit per test 1 second memory limit per test 256 megabytes input stand ...
随机推荐
- Chromedriver 的安装与配置
首先是下载网址:https://sites.google.com/a/chromium.org/chromedriver/downloads(需要FQ,用Browser浏览器即可翻进,版本要和Chro ...
- JavaScript中检测数组的几种方式
检测一个对象是否为数组的方式有: Array.isArray() // true或false(es5) toString.call([]); // [object Arr ...
- python 面试题(1)
好用简洁的大数据技术:python.hadoop.R 慢慢学习,随时分享 1.什么是Python?使用Python有什么好处? Python是一种编程语言,它有对象.模块.线程.异常处理和自动内存管理 ...
- 洛谷 P1976 鸡蛋饼
题目背景 Czyzoiers 都想知道小 x 为什么对鸡蛋饼情有独钟.经过一番逼问,小 x 道出 了实情:因为他喜欢圆. 题目描述 最近小 x 又发现了一个关于圆的有趣的问题:在圆上有2N 个不同的点 ...
- [洛谷P1338] 末日的传说
洛谷题目链接:末日的传说 题目描述 只要是参加jsoi活动的同学一定都听说过Hanoi塔的传说:三根柱子上的金片每天被移动一次,当所有的金片都被移完之后,世界末日也就随之降临了. 在古老东方的幻想乡, ...
- redhat 7 安装oracle12.1
https://oracle-base.com/articles/12c/oracle-db-12cr1-installation-on-oracle-linux-7 一定要配置yum本地源 ...
- 【NOIP】普及组2011 表达式的值
[算法]动态规划+后缀表达式 [题解] 先把算式转为后缀表达式后进行DP 令f[s][0]表示使表达式答案为0的方案数 f[s][1]表示使表达式答案为1的方案数 (加法) f[a+b][1]=f[a ...
- rabbitmq之队列性能测试及优化方法(六)
前言 下面关注一下rabbitmq实际使用时的性能问题和怎么进行一些优化. 性能测试 针对每个需要生产/消费者与rabbitmq进行通讯的方法进行测试 测试环境 排除网络IO的干扰,采用生产者和消费者 ...
- jQuery Validate插件 验证实例
官网地址:http://bassistance.de/jquery-plugins/jquery-plugin-validation Validate手册: http://www.cnblogs.co ...
- monkey测试===Android测试工具Monkey用法简介(转载)
Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中.它向系统发送伪随机的用户事件流(如按键输入.触摸屏输入.手势输入等),实现对正在开发的应用程序进行压力测试.Monkey ...