Sum in the tree CodeForces - 1098A

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

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

Output

1

Input

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

Output

2

Input

3
1 2
2 -1 1

Output

-1

题意:给出一棵树,以及每个节点到根节点的路径上经过的所有点的权值之和(包括这个节点在内),其中题目把所有深度为偶数的节点的信息全部擦除了,也就是用-1表示,让你求最终所有点权之和(要求最小)。

思路:dfs,找节点为-1的点,按照贪心思想,该点的上的sum值为其子节点sum值的最小值。若为-1的点为叶子,那么sum值为其父亲的sum值。然后再dfs一次,点i的点权为sum[i]-sum[father],如果该值小于0,那么直接输出-1

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=100009;
int head[maxn],cnt,flag;
ll sum[maxn],ans[maxn];
struct node{
	int id;
	int next;
}side[maxn];
void init()
{
	memset(head,-1,sizeof(head));
	memset(sum,0,sizeof(sum));
	memset(ans,0,sizeof(ans));
	cnt=flag=0;
}
void add(int x,int y)
{
	side[cnt].id=y;
	side[cnt].next=head[x];
	head[x]=cnt++;
}
void dfs1(int x,int fa)
{
	ll minn=0x3f3f3f3f;
	if(sum[x]==-1)
	{
		for(int i=head[x];i!=-1;i=side[i].next)
		{
			int y=side[i].id;
			if(y==fa) continue;
			minn=min(minn,sum[y]);
			dfs1(y,x);
		}
		if(minn!=0x3f3f3f3f)
			sum[x]=minn;
		else
			sum[x]=sum[fa];
	}
	else
	{
		for(int i=head[x];i!=-1;i=side[i].next)
		{
			int y=side[i].id;
			if(y==fa) continue;
			dfs1(y,x);
		}
	}
}
void dfs2(int x,int fa)
{
	for(int i=head[x];i!=-1;i=side[i].next)
	{
		int y=side[i].id;
		if(y==fa) continue;
		ans[y]=sum[y]-sum[x];
		if(ans[y]<0)
		{
			flag=1;
			return ;
		}
		dfs2(y,x);
	}
}
int main()
{
	int n,x;
	scanf("%d",&n);
	init();
	for(int i=2;i<=n;i++)
	{
		scanf("%d",&x);
		add(x,i);
	}
	for(int i=1;i<=n;i++)
		scanf("%lld",&sum[i]);
	dfs1(1,-1);
	dfs2(1,-1);
	
	ans[1]=sum[1];
	ll res=0;
//	for(int i=1;i<=n;i++)
//	{
//		printf("%d %d\n",ans[i],sum[i]);
//	}
	for(int i=1;i<=n;i++)
		if(ans[i]>0)
			res+=ans[i];
	if(!flag)
		printf("%lld\n",res);
	else
		printf("-1\n");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/why932346109/article/details/88426274