Codeforces Round #530 (Div. 2) 1099D D. Sum in the tree

D. Sum in the tree

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

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.

Input

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

Output one integer — the minimum total sum of all values avav in the original tree, or −1−1 if such tree does not exist.

Examples

input

Copy

5
1 1 1 1
1 -1 -1 -1 -1

output

Copy

1

input

Copy

5
1 2 3 1
1 -1 2 -1 -1

output

Copy

2

input

Copy

3
1 2
2 -1 1

output

Copy

-1

 

题意:给你一颗树,然后他会擦出偶数度的节点数值(即样例中的-1),不为-1的a[i],代表的是从i节点到根节点1,整个路径上节点权值的总和。

现在让你恢复所有擦除地方的权值,并且把整棵树所有的权值都求出,要求最小,如果不能恢复则输出-1

 

 

首先,可以发现我们可以根据叶子节点的值,然后一层层的往上推算价值,如果是叶子节点的-1,那么可以直接算作0(后面会讲),当前不做贡献,如果是一个val,那么我们就要拿他去和上上一层的val去比较(因为上一层是-1),如果大于等于上上一层节点的值,就可以算节点值,小于的话,则不满足恢复,直接-1即可,

现在对这个图举例,4 , 5 节点先由 ans[4] = 10 - 3 = 7  , ans[5] = 12 - 3 = 9, 分别赋值后,递归到2节点的时候,对于-1,我们要去用贪心的策略来让树上所有权值节点最小,那么应该怎么做呢?4,5节点可以取一个Min,然后直接赋值给2节点,更新4,5,这样我们就少了一次9的权值,使得权值尽量小了。

 

代码如下:


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int>  P;
vector<vector<ll> >v;
const int maxn = 2e6;
ll ans[maxn];
ll val[maxn];
int dfs(ll x,ll fa,ll tmp) {
//    cout << x << "   " << fa << "   " << tmp << endl;
    if(val[x] != -1 && val[x] < tmp) {
        cout << -1 << endl;
        exit(0);
    }
    for(auto const d:v[x]) {
        if(d != fa) {
            if(val[x] < 0) {   dfs(d,x,tmp) ;
            }else  dfs(d,x,val[x]);
        }
    }
    if(val[x] >= 0){
        if(x == 4 || x == 5){cout << "dsadasd" << endl;
            cout << tmp << "   "  << val[x] << endl;
        }
        ans[x] = val[x] - tmp;
    }else{
        ll Min = 1e18;
        for(auto const d:v[x]) Min = min(Min,ans[d]);
        if(Min != 1e18) {
            for(auto const d:v[x]) ans[d] -= Min;
            ans[x] = Min;
        }else{
            ans[x] = 0;
        }
    }
    return  0;
}
int n;
int main() {
    while(cin >> n) {
            memset(ans,0,sizeof(ans));
        v.clear();
        v.resize(n + 50);
        for(int i = 2; i <= n; i++) {
            int x;
            cin >> x;
            v[x].push_back(i);
        }
        for(int i = 1; i <= n; i++)
            cin >> val[i];
        dfs(1,0,0);
        ll Ans = 0;
        for(int i = 1;i <= n;i++) cout << ans[i] << endl;

        for(int i = 1;i <= n;i++) Ans += ans[i];
        cout << Ans << endl;
    }
    return 0;
}

//5
//1 1 2 2
//1 -1 -1 10 12

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值