Codeforces - 1098A - Sum in the tree

140 篇文章 0 订阅
91 篇文章 0 订阅

地址

https://codeforces.com/contest/1098/problem/A

原文地址

https://www.lucien.ink/archives/400/

题意

给出一棵有点权的树,跟节点深度为 1 1 1 ,现在你只知道深度为奇数的点到数根的路经权值和,让你给所有点都分配一个非负的权值,满足所给和,且所有点权的和最小。如果不存在输出 − 1 -1 1

题解

对于权值和未知的节点,让他们的点权最大即可。

代码

https://pasteme.cn/4440

#include <bits/stdc++.h>
typedef long long ll;
const int maxn = int(1e5) + 7;
std::vector<int> edge[maxn];
int n, dep[maxn];
ll sum[maxn], ans;
void dfs(int u, int pre = 0) {
	dep[u] = dep[pre] + 1;
	if (dep[u] & 1) for (int v : edge[u]) dfs(v, u);
	else {
		if (edge[u].empty()) sum[u] = sum[pre];
		else {
		    sum[u] = 0x3f3f3f3f;
			for (int v : edge[u]) {
				dfs(v, u);
				sum[u] = std::min(sum[u], sum[v]);
			}
		}
	}
}
void calc(int u, int pre = 0) {
	if (sum[u] < sum[pre]) {
		puts("-1");
		exit(0);
	}
	ans += sum[u] - sum[pre];
	for (int v : edge[u])
	    calc(v, u);
}
int main() {
	scanf("%d", &n);
	for (int i = 2, pre; i <= n; i++) scanf("%d", &pre), edge[pre].push_back(i);
	for (int i = 1; i <= n; i++) scanf("%lld", sum + i);
	dfs(1);
	calc(1);
	printf("%lld\n", ans);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值