题目链接:Codeforces - Sum in the tree
显然每个点尽量放在深度小的地方,这样一定是最优的,但是要保证答案是正确的,所以放的值不超过儿子的最小值。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e5+10;
int a[N],deg[N],f[N],n,s[N]; long long res;
vector<int> g[N];
void dfs(int x){
res+=a[x];
for(auto to:g[x]){
a[to]=s[to]-s[x]; dfs(to);
}
}
signed main(){
cin>>n;
for(int i=2;i<=n;i++)
scanf("%d",&f[i]),g[f[i]].push_back(i),deg[i]++,deg[f[i]]++;
for(int i=1;i<=n;i++) scanf("%d",&s[i]);
for(int i=1;i<=n;i++) if(s[i]==-1){
if(deg[i]==1) s[i]=s[f[i]];
else{
int mi=1e9;
for(auto to:g[i]) mi=min(mi,s[to]);
s[i]=mi;
}
}
a[1]=s[1]; dfs(1);
for(int i=1;i<=n;i++) if(a[i]<0) return puts("-1"),0;
cout<<res;
return 0;
}