#pragma GCC optimize(2) #include<bits/stdc++.h> #define ll long long #define maxn 1000005 #define inf 2e9 using namespace std; inline int read() { int x=0,w=1; char c=getchar(); while(c<'0'||c>'9') { if(c=='-') w=-1; c=getchar(); } while(c<='9'&&c>='0') { x=(x<<1)+(x<<3)+c-'0'; c=getchar(); } return w==1?x:-x; } ll n,t1,t2,t3,f[maxn],s1[maxn],s2[maxn],ans; struct node { ll a,b,c,id,w1,w2; } p[maxn]; vector <int> mp[maxn]; inline void dfs(int u,int fa) { f[u]=fa; s1[u]=p[u].w1;//子树中点的权值 s2[u]=p[u].w2; for(int i=0; i<mp[u].size(); i++) { int v=mp[u][i]; if(v==fa) continue; dfs(v,u); s1[u]+=s1[v]; s2[u]+=s2[v]; } } // 父节点 父节点代价 inline void dfs2(int u,int fa,ll mn) { for(int i=0; i<mp[u].size(); i++) { int v=mp[u][i]; if(v==fa) continue; if(p[u].a<mn) //当前点代价小于父节点 { ll tmp=min(s1[u],s2[u]); ans+=tmp*p[u].a*2; ans-=tmp*mn*2; mn=p[u].a; } dfs2(v,u,mn); } } int main() { n=read(); for(int i=1; i<=n; i++) { p[i].a=read(),p[i].b=read(),p[i].c=read(); t1+=p[i].b; t2+=p[i].c; p[i].id=i; if(p[i].b!=p[i].c)//如果需要变换 { if(p[i].b==0) //初始值是0,则需要变成1,就是w1 p[i].w1=1; else p[i].w2=1; //初始值是1,需要变成0, 就是w2 } } if(t1!=t2) return puts("-1"),0;//有的总和 与 要的总和不等 直接结束 for(int i=1; i<=n-1; i++) { int u=read(),v=read(); mp[u].push_back(v); mp[v].push_back(u); } dfs(1,0); ans=p[1].a*min(s1[1],s2[1])*2;//直接拿根节点去搞答案 for(int i=0; i<mp[1].size(); i++) { int v=mp[1][i]; dfs2(v,1,p[1].a); } cout<<ans<<endl; return 0; }