首 先 , 当 b i 和 c i 不 符 合 的 个 数 中 , b i 为 1 的 个 数 和 c i 为 0 的 个 数 不 相 等 时 首先,当b_i和c_i不符合的个数中,b_i为1的个数和c_i为0的个数不相等时 首先,当bi和ci不符合的个数中,bi为1的个数和ci为0的个数不相等时
输 出 − 1 , 这 是 显 然 的 , 因 为 我 们 只 能 重 新 排 列 输出-1,这是显然的,因为我们只能重新排列 输出−1,这是显然的,因为我们只能重新排列
然 后 考 虑 如 何 得 到 最 优 \color{Red}{然后考虑如何得到最优} 然后考虑如何得到最优
先 明 确 一 点 , 如 果 在 以 u 为 根 的 子 树 中 先明确一点,如果在以u为根的子树中 先明确一点,如果在以u为根的子树中
b i 为 1 但 c i 为 0 的 个 数 记 作 o n e b_i为1但c_i为0的个数记作one bi为1但ci为0的个数记作one
b i 为 0 但 c i 为 1 的 个 数 记 作 z e r o b_i为0但c_i为1的个数记作zero bi为0但ci为1的个数记作zero
那 我 们 最 多 可 以 在 子 树 中 选 m i n ( o n e , z e r o ) ∗ 2 个 节 点 进 行 重 排 ( 保 证 0 和 1 个 数 相 等 ) 那我们最多可以在子树中选min(one,zero)*2个节点进行重排(保证0和1个数相等) 那我们最多可以在子树中选min(one,zero)∗2个节点进行重排(保证0和1个数相等)
开 始 我 是 想 先 选 掉 代 价 最 小 的 子 树 中 的 , 但 是 这 样 不 好 考 虑 ! ! 开始我是想先选掉代价最小的子树中的,但是这样不好考虑!! 开始我是想先选掉代价最小的子树中的,但是这样不好考虑!!
不 妨 我 们 先 假 设 在 根 节 点 1 的 所 有 子 树 中 全 选 节 点 不妨我们先假设在根节点1的所有子树中全选节点 不妨我们先假设在根节点1的所有子树中全选节点
此 时 代 价 a n s 是 所 有 b i 和 c i 不 同 节 点 个 数 ∗ a 1 此时代价ans是所有b_i和c_i不同节点个数*a_1 此时代价ans是所有bi和ci不同节点个数∗a1
然 后 往 下 d f s , 如 果 碰 到 a i 更 下 的 节 点 v , 说 明 v 的 子 树 不 需 要 根 节 点 来 重 排 然后往下dfs,如果碰到a_i更下的节点v,说明v的子树不需要根节点来重排 然后往下dfs,如果碰到ai更下的节点v,说明v的子树不需要根节点来重排
所 以 让 答 案 减 小 一 些 , 也 就 是 a n s − = m i n ( o n e v , z e r o v ) ∗ 2 ∗ ( a v − a 1 ) 所以让答案减小一些,也就是ans-=min(one_v,zero_v)*2*(a_v-a_1) 所以让答案减小一些,也就是ans−=min(onev,zerov)∗2∗(av−a1)
再 往 下 又 碰 到 更 好 的 节 点 , 那 么 那 个 节 点 又 可 以 不 用 v 重 排 而 自 己 重 排 . . . . . . 再往下又碰到更好的节点,那么那个节点又可以不用v重排而自己重排...... 再往下又碰到更好的节点,那么那个节点又可以不用v重排而自己重排......
至 于 找 到 每 个 节 点 为 根 的 子 树 的 z e r o 和 o n e 预 处 理 一 下 就 好 了 至于找到每个节点为根的子树的zero和one预处理一下就好了 至于找到每个节点为根的子树的zero和one预处理一下就好了
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=4e5+10;
ll ans;
struct p{
int to,nxt;
}d[maxn];int head[maxn],cnt=1;
ll a[maxn],b[maxn],c[maxn];
void add(int u,int v){
d[cnt].to=v,d[cnt].nxt=head[u],head[u]=cnt++;
}
ll dp[maxn][2];
void pre(int now,int fa)
{
if(b[now]==1&&c[now]==0) dp[now][1]++;
else if(b[now]==0&&c[now]==1) dp[now][0]++;
for(int i=head[now];i;i=d[i].nxt)
{
int v=d[i].to;
if(v==fa) continue;
pre(v,now);
dp[now][0]+=dp[v][0];
dp[now][1]+=dp[v][1];
}
}
void dfs(int now,int fa,ll nice)
{
if(a[now]<nice)
ans-=min(dp[now][0],dp[now][1])*2*(nice-a[now]);
for(int i=head[now];i;i=d[i].nxt)
{
int v=d[i].to;
if(v==fa) continue;
dfs(v,now,min(nice,a[now]));
}
}
int main()
{
int n,one=0,zero=0;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i]>>b[i]>>c[i];
if(b[i]==1&&c[i]==0) one++;
else if(b[i]==0&&c[i]==1) zero++;
}
for(int i=1;i<n;i++)
{
int l,r;
scanf("%d%d",&l,&r);
add(l,r);add(r,l);
}
if(one!=zero) cout<<-1;
else
{
pre(1,0);
ans=a[1]*(one+zero);
dfs(1,0,a[1]);//代价为a[1]
cout<<ans;
}
}