#define _USE_MATH_DEFINES #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; template class LowestCommonAncestor { private: vector > to; // ダブリング先のノード vector depth; // 根からの深さ vector sum; // 根までのノード値の合計 int climb(int curr, int dist) { int i = 0; while(dist > 0){ if(dist % 2 == 1) curr = to[curr][i]; dist /= 2; ++ i; } return curr; } public: LowestCommonAncestor(const vector >& edges, const vector& val, int root) { int n = edges.size(); to.assign(n, vector()); sum.assign(n, 0); depth.assign(n, 0); queue > q; q.push(make_pair(root, -1)); sum[root] = val[root]; int cnt = 0; while(!q.empty()){ int m = q.size(); while(--m >= 0){ int curr, prev; tie(curr, prev) = q.front(); q.pop(); if(prev != -1){ to[curr].push_back(prev); int j = prev; for(unsigned k=0; k=0; --i){ if(i < (int)to[a].size() && to[a][i] != to[b][i]){ a = to[a][i]; b = to[b][i]; } } return to[a][0]; } // ノードの深さを取得 int getDepth(int a) { return depth[a]; } // 2つのノード間にあるノード値の合計を取得 T getSum(int a, int b) { int c = getAncestor(a, b); T ans = sum[a] + sum[b] - sum[c]; if(!to[c].empty()){ int d = to[c][0]; ans -= sum[d]; } return ans; } }; int main() { int n; cin >> n; vector > edges(n); for(int i=0; i> a >> b; edges[a].push_back(b); edges[b].push_back(a); } vector u(n); for(int i=0; i> u[i]; int m; cin >> m; LowestCommonAncestor lca(edges, u, 0); long long ans = 0; for(int i=0; i> a >> b >> c; ans += lca.getSum(a, b) * c; } cout << ans << endl; return 0; }