#include using namespace std; using vi = vector; using vvi = vector>; class RMQidx{ private: int n; // size of val vector> idx; // doubling range min index. idx[k][p]: index of min(val[p:p+2^k]) including p and not including p+2^k. vector val; void init(const vector &src){ n = src.size(); val = src; idx.emplace_back(vector(n, 0)); for (int i = 0; i != n; ++i) idx[0][i] = i; for (int k = 0, r = 1; r < n; ++k, r <<= 1){ idx.emplace_back(idx[k]); for (int p = 0; p + r < n; ++p){ auto idxL = idx[k][p]; auto idxR = idx[k][p + r]; idx[k + 1][p] = (val[idxL] > val[idxR]) ? idxR : idxL; } } } public: RMQidx(): n(0), idx(vector>()), val(vector()) {} RMQidx(const vector &src){init(src);} int query(int L, int R){ // index of min(data[0][L..R] including both ends. [L, R] assert(L <= R); if (L == R) return L; int k = 31 - __builtin_clz(R - L); auto idxL = idx[k][L]; auto idxR = idx[k][R + 1 - (1 << k)]; return (val[idxL] > val[idxR])? idxR: idxL; } }; class LCA{ private: int n; // number of vertexes int root; const vector> & Es; vector height; // height[v] = height of vertex v. vector i2v; // i2v[i] = v. Euler tour order of vertexes. vector v2i; // v2i[v] = i. Last position of vertex v in the Euler tour. RMQidx rmq; // Range Minimum Query object which returns the position (idx) of the minimum value in the euler tour. void dfs(int v, int h){ height[v] = h; i2v.push_back(v); for (auto u : Es[v]){ if (height[u] == -1) { dfs(u, h + 1); i2v.push_back(v); } } } public: LCA(const vector> &_Es, int _root = 0):Es(_Es){ n = Es.size(); root = _root; height = vector(n, -1); v2i = vector(n, -1); dfs(root, 0); assert(i2v.size() == 2 * n - 1); vector val(2 * n - 1); for (int i = 0; i != 2 * n - 1; ++i) { val[i] = height[i2v[i]]; v2i[i2v[i]] = i; } rmq = RMQidx(val); } int query(int u, int v){ // returns lowest common ancestor of vertex u and vertex v. int i = v2i[u]; int j = v2i[v]; if (i > j) swap(i, j); return i2v[rmq.query(i, j)]; } int dist(int u, int v){ // returns the distance between vertex u and vertex v. int k = query(u, v); return height[u] + height[v] - 2 * height[k]; } }; void dfs_et(int v, int p, vi & euler_tour, const vvi & Es){ // v: current vertex, p: parent of v euler_tour.push_back(v); for (auto u : Es[v]){ if (u == p) continue; dfs_et(u, v, euler_tour, Es); euler_tour.push_back(v); } } vi get_euler_tour(const vvi &Es, int root = 0){ vi euler_tour; int nV = Es.size(); dfs_et(root, -1, euler_tour, Es); return euler_tour; } vi get_first_pos(const vi & et, int N){ vi first(N, -1); for (int i = 0; i < et.size(); ++i){ if (first[et[i]] == -1) first[et[i]] = i; } return first; } vi get_last_pos(const vi & et, int N){ vi last(N, -1); for (int i = 0; i < et.size(); ++i){ last[et[i]] = i; } return last; } int main() { int N; cin >> N; vector> Es(N); for (int i = 1; i < N; ++i){ int a, b; cin >> a >> b; Es[a].push_back(b); Es[b].push_back(a); } LCA lca(Es); vi Us(N); for (auto & u : Us) cin >> u; auto euler_tour = get_euler_tour(Es); auto first = get_first_pos(euler_tour, N); auto last = get_last_pos(euler_tour, N); vector imos(2*N - 1, 0); int M; cin >> M; while (M--){ int a, b, c; cin >> a >> b >> c; int d = lca.query(a, b); imos[first[a]] += c; imos[first[b]] += c; if (d != 0) imos[first[d] - 1] -= c; imos[first[d]] -= c; } vector cum(2 * N - 1, 0); cum[0] = imos[0]; for (int i = 1; i < cum.size(); ++i){ cum[i] = cum[i - 1] + imos[i]; } long long cost = 0; cost += Us[0] * cum[last[0]]; for (int i = 1; i < N; ++i){ cost += Us[i] * (cum[last[i]] - cum[first[i] - 1]); } cout << cost; return 0; }