#include #include #include #include #include #include #include #include #include #include #include #include #include #define repd(i,a,b) for (int i=(int)(a);i<(int)(b);i++) #define rep(i,n) repd(i,0,n) #define all(x) (x).begin(),(x).end() #define mod 1000000007 #define inf 2000000007 #define mp make_pair #define pb push_back typedef long long ll; using namespace std; template inline void output(T a, int p) { if(p) cout << fixed << setprecision(p) << a << "\n"; else cout << a << "\n"; } // end of template // least common ancestor class LCA{ public: int V; int logV, id = 0; vector>> G; // graph: vertex, distance vector depth, dist; vector> parent; vector L, R, I; LCA(int n){ V = n; G.resize(V); depth.resize(V); dist.resize(V); L.resize(V), R.resize(V), I.resize(V); logV = 0; while (V >= (1 << logV)) logV++; parent.resize(logV, vector(V)); } // determine depth and distance from root void init(int v = 0, int par = -1, int d = 0, int l = 0) { // root: v = 0, init(0, -1, 0, 0) depth[v] = d; parent[0][v] = par; dist[v] = l; I[id] = v; L[v] = id++; rep(i, G[v].size()){ int w = G[v][i].first; int lc = G[v][i].second; if (w == par) continue; init(w, v, d + 1, lc + l); } R[v] = id; } void build() { for (int k = 0; k + 1 < logV; k++) { for (int v = 0; v < V; v++) { if (parent[k][v] < 0) parent[k+1][v] = -1; else parent[k+1][v] = parent[k][parent[k][v]]; } } } void add(int v1, int v2, int dist = 0){ G[v1].pb(mp(v2, dist)); G[v2].pb(mp(v1, dist)); } int query(int u, int v) { if (depth[u] > depth[v]) swap(u, v); for (int k = 0; k < logV; k++) { if ((depth[v] - depth[u]) >> k & 1) v = parent[k][v]; } if (u == v) return u; for (int k = logV - 1; k >= 0; k--) { if (parent[k][u] != parent[k][v]) { u = parent[k][u]; v = parent[k][v]; } } return parent[0][u]; } }; vector dist; void dfs(vector>> &G, vector &U, int pre = -1, int cur = 0, int cost = 0){ dist[cur] = cost + U[cur]; for(auto v: G[cur]){ if(v.first != pre){ dfs(G, U, cur, v.first, dist[cur]); } } } int main() { cin.tie(0); ios::sync_with_stdio(0); // source code int N; cin >> N; LCA lca(N); rep(i, N - 1){ int A, B; cin >> A >> B; lca.add(A, B); } lca.init(); lca.build(); auto G = lca.G; dist.resize(N); vector U(N); rep(i, N) cin >> U[i]; dfs(G, U); int M; cin >> M; ll ret = 0; rep(i, M){ int A, B, C; cin >> A >> B >> C; ret += (ll)(dist[A] + dist[B] - 2 * dist[lca.query(A, B)] + U[lca.query(A, B)]) * C; // cout << A << ", " << B << ": " << lca.query(A, B) << endl; } output(ret, 0); return 0; }