我们发现,在一个节点处进行操作等价于在它的祖先处进行操作。
于是我们就有一个想法:将每一个节点的费用改成从它到根的路径上点的费用的最小值。
然后我们发现,在深度深的节点处操作肯定比在深度浅的节点处操作更优,证明显然。
那么直接一遍 dfs,在尽量深的节点处操作,最后计算总费用输出即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair <int, int> PII;
inline int gi()
{
int f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return f * x;
}
const int INF = 0x3f3f3f3f, N = 200003, M = N << 1;
int n, m;
int a[N], b[N], c[N];
int tot, head[N], ver[M], nxt[M];
LL qz;
inline void add(int u, int v)
{
ver[++tot] = v, nxt[tot] = head[u], head[u] = tot;
}
PII dfs(int u, int f, int mn)
{
PII tmp = make_pair(0, 0);
if (b[u] != c[u])
{
if (c[u] == 1) ++tmp.second;
else ++tmp.first;
}
for (int i = head[u]; i; i = nxt[i])
{
int v = ver[i];
if (v == f) continue;
PII tmpp = dfs(v, u, min(mn, a[v]));
tmp.first += tmpp.first, tmp.second += tmpp.second;
}
int need = min(tmp.second, tmp.first);
qz += 2ll * need * mn;
tmp.first -= need, tmp.second -= need;
return tmp;
}
int main()
{
int T = 1;
while (T--)
{
n = gi();
int to1 = 0, to0 = 0;
for (int i = 1; i <= n; i+=1)
{
a[i] = gi(), b[i] = gi(), c[i] = gi();
if (b[i] != c[i])
{
if (c[i] == 1) ++to1;
else ++to0;
}
}
for (int i = 1; i < n; i+=1)
{
int u = gi(), v = gi();
add(u, v), add(v, u);
}
if (to0 != to1) {puts("-1"); continue;}
PII ans = dfs(1, 0, a[1]);
if (ans.first || ans.second) puts("-1");
else printf("%lld
", qz);
}
return 0;
}