题目链接
解题报告:
从根节点开始,从上至下维护节点的 ai 最小值及需转换的0 /1个数
再从下至上进行处理。
#include <bits/stdc++.h>
#define ll long long
#define f first
#define s second
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=2e5+10;
const ll MOD=1e9+7;
pii p[maxn];
struct TMD{
int to,next;
}edge[maxn<<1];
int head[maxn],cnt,n;
int sx[maxn],sy[maxn],q[maxn];
ll ans=0;
void add(int from,int to)
{
edge[++cnt]={to,head[from]};
head[from]=cnt;
}
void dfs(int now,int pre,int Mi)
{
// sx 1
// sy 0
if(p[now].f!=p[now].s){
if(p[now].f==1) sx[now]=1,sy[now]=0;
else sy[now]=1,sx[now]=0;
}
else sx[now]=sy[now]=0;
for(int i=head[now];~i;i=edge[i].next) {
int to = edge[i].to;
if (to == pre) continue;
dfs(to, now, min(Mi,q[to]));
sx[now] += sx[to];
sy[now] += sy[to];
}
//cout<<now<<" "<<sx[now]<<" "<<sy[now]<<endl;
if(q[now]<=Mi){
if(sx[now]>0&&sy[now]>0){
int mi=min(sx[now],sy[now]);
sx[now]-=mi,sy[now]-=mi;
ans+=2ll*q[now]*mi;
}
}
}
int main() {
mem(head,-1);
int u,v;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&q[i],&p[i].f,&p[i].s);
}
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs(1,0,q[1]);
if(sx[1]==0&&sy[1]==0)printf("%lld\n",ans);
else printf("-1\n");
return 0;
}