#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long ll; typedef pair P; typedef pair PL; const ll MOD = 1000000007; const int mod = 1000000007; ll INF = 1LL << 60; template istream &operator>>(istream &is, vector &vec) { for (auto &v : vec) is >> v; return is; } template ostream &operator<<(ostream &os, const vector &vec) { os << "["; for (auto v : vec) os << v << ","; os << "]"; return os; } template ostream &operator<<(ostream &os, const deque &vec) { os << "deq["; for (auto v : vec) os << v << ","; os << "]"; return os; } template ostream &operator<<(ostream &os, const set &vec) { os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; } template ostream &operator<<(ostream &os, const unordered_set &vec) { os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; } template ostream &operator<<(ostream &os, const multiset &vec) { os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; } template ostream &operator<<(ostream &os, const unordered_multiset &vec) { os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; } template ostream &operator<<(ostream &os, const pair &pa) { os << "(" << pa.first << "," << pa.second << ")"; return os; } template ostream &operator<<(ostream &os, const map &mp) { os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; } template ostream &operator<<(ostream &os, const unordered_map &mp) { os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }; #define dbg(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl; template void Fill(A (&array)[N], const T &val) { fill((T *)array, (T *)(array + N), val); } struct LCA { int n, h; vector> par; vector>> v; vector depth, dis; LCA(int sz) : n(sz), v(n), depth(n), dis(n) { h = 1; while ((1 << h) < n) h++; par.assign(h, vector(n, -1)); } void add_edge(int x, int y, int z) { v[x].push_back({y, z}); v[y].push_back({x, z}); } void dfs(int x, int p, int d, ll di) { par[0][x] = p; depth[x] = d; dis[x] = di; for (auto to : v[x]) if (to.first != p) dfs(to.first, x, d + 1, di + to.second); } void build() { dfs(0, -1, 0, 0); for(int i=0; i < h-1; i++) { for(int j=0; j < n; j++) { if (par[i][j] < 0) par[i + 1][j] = -1; else par[i + 1][j] = par[i][par[i][j]]; } } } int lca(int u, int v) { if (depth[u] > depth[v]) swap(u, v); for(int i=0; i < h; i++) if ((depth[v] - depth[u]) >> i & 1) v = par[i][v]; if (u == v) return u; for (int i = h - 1; i >= 0; i--) { if (par[i][u] != par[i][v]) { u = par[i][u]; v = par[i][v]; } } return par[0][u]; } ll dist(int u, int v) { return dis[u] + dis[v] - 2 * dis[lca(u, v)]; } }; int solve() { ll n; cin >> n; LCA lca(n); for(int i=0; i < n-1; i++){ ll u, v, w; cin >> u >> v >> w; lca.add_edge(u, v, w); } lca.build(); ll q; cin >> q; while (q--) { ll a,b,c; cin >> a >> b >> c; cout << (lca.dist(a,b) + lca.dist(b,c) + lca.dist(c,a))/2 << endl; } return 0; } int main() { //cout.precision(10) ios::sync_with_stdio(false); cin.tie(0); solve(); }