Problem:
Score : 400 points

Problem Statement

You are given a tree with N vertices.

Here, a tree is a kind of graph, and more specifically, a connected undirected graph with N-1 edges, where N is the number of its vertices.

The i-th edge (1≤i≤N-1) connects Vertices a_i and b_i, and has a length of c_i.

You are also given Q queries and an integer K. In the j-th query (1≤j≤Q):

find the length of the shortest path from Vertex x_j and Vertex y_j via Vertex K.

Constraints

3≤N≤10^5

1≤a_i,b_i≤N (1≤i≤N-1)

1≤c_i≤10^9 (1≤i≤N-1)

The given graph is a tree.

1≤Q≤10^5

1≤K≤N

1≤x_j,y_j≤N (1≤j≤Q)

x_j≠y_j (1≤j≤Q)

x_j≠K,y_j≠K (1≤j≤Q)

Input

Input is given from Standard Input in the following format:

N
a_1 b_1 c_1
:
a_{N-1} b_{N-1} c_{N-1}
Q K
x_1 y_1
:
x_{Q} y_{Q}

Output

Print the responses to the queries in Q lines.

In the j-th line j(1≤j≤Q), print the response to the j-th query.

Sample Input 1

5
1 2 1
1 3 1
2 4 1
3 5 1
3 1
2 4
2 3
4 5

Sample Output 1

3
2
4

The shortest paths for the three queries are as follows:

Query 1: Vertex 2 → Vertex 1 → Vertex 2 → Vertex 4 : Length 1+1+1=3

Query 2: Vertex 2 → Vertex 1 → Vertex 3 : Length 1+1=2

Query 3: Vertex 4 → Vertex 2 → Vertex 1 → Vertex 3 → Vertex 5 : Length 1+1+1+1=4

Sample Input 2

7
1 2 1
1 3 3
1 4 5
1 5 7
1 6 9
1 7 11
3 2
1 3
4 5
6 7

Sample Output 2

5
14
22

The path for each query must pass Vertex K=2.

Sample Input 3

10
1 2 1000000000
2 3 1000000000
3 4 1000000000
4 5 1000000000
5 6 1000000000
6 7 1000000000
7 8 1000000000
8 9 1000000000
9 10 1000000000
1 1
9 10

Sample Output 3

17000000000

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;

constexpr int si = 101 * 1002, si_log = 8 + 10 + 1, mod = static_cast<int>(1e9) + 7;
constexpr int shi = 101 * 1000;
int n, m,k, depth[si], lca_par[si_log][si], time_cnt, time_in[si], time_out[si];
int64_t lca_cost[si_log][si];
//cost, to
vector<pair<int, int>> gr[si];

void vi(const int u = 1) {
   const int par = lca_par[0][u];
   depth[u] = depth[par] + 1;
   time_in[u] = ++time_cnt;
   for (const auto &p : gr[u]) {
      if (p.second == par) continue;
      lca_par[0][p.second] = u;
      //lca_max_cost[0][p.second] = p.first;
      lca_cost[0][p.second] = lca_cost[0][u] + p.first;
      vi(p.second);
   }
   time_out[u] = ++time_cnt;
}
inline bool is_parent(int p, int c)
{
   auto ret = time_in[p] <= time_in[c] && time_out[c] <= time_out[p];
   return ret;
}

//cost, node
pair<int64_t, int> lca(int u, int v) {
   if (depth[v] < depth[u])
      swap(u, v);
   //if (is_parent(u, v)) return u;

   int64_t mc = 0;// depth[u] <= depth[v]
   for (int j = si_log - 1; 0 <= j; --j) {
      const auto &z = lca_par[j][v];
      if (depth[u] <= depth[z]) {
         //mc = max(mc, lca_max_cost[j][v]);
         mc = max(mc, lca_cost[j][v]);
         v = z;
      }
   }
   if (u == v)
      return make_pair(mc, u);
   for (int j = si_log - 1; 0 <= j; --j) {
      const auto &q = lca_par[j][u];
      const auto &w = lca_par[j][v];
      if (q != w) {
         //mc = max({ mc, lca_max_cost[j][u], lca_max_cost[j][v] });
         mc = max({ mc, lca_cost[j][u], lca_cost[j][v] });
         u = q;
         v = w;
      }
   }
   //mc = max({ mc, lca_max_cost[0][u], lca_max_cost[0][v] });
   mc = max({ mc, lca_cost[0][u], lca_cost[0][v] });
   return make_pair(mc, lca_par[0][u]);
}
int lca_dist(int a, int b) {
   auto r = lca(a, b);
   int c = r.second;
   auto ret = depth[a] + depth[b] - 2 * depth[c];
   return ret;
}
int64_t cost_dist(int a, int b) {
   auto r = lca(a, b);
   int c = r.second;//a-c-b
   auto ret = lca_cost[0][a] + lca_cost[0][b] - 2 * lca_cost[0][c];
   return ret;
}
//a .. b .. c
bool is_path(int a, int b, int c) {
   const auto ac = lca_dist(a, c),
      ab = lca_dist(a, b),
      bc = lca_dist(b, c);
   auto ret = ac == (ab + bc);
   return ret;
}
void propa() {
   for (int j = 1; j < si_log; j++)
      for (int i = 1; i <= n; i++) {
         const auto &prev = lca_par[j - 1][i];
         lca_par[j][i] = lca_par[j - 1][prev];
         //lca_max_cost[j][i] = max(lca_max_cost[j - 1][i], lca_max_cost[j - 1][prev]);
         lca_cost[j][i] = lca_cost[j - 1][i] + lca_cost[j - 1][prev];
      }
}
int64_t sol(const int x, const int y){
   auto r = cost_dist(x, k),
   c = cost_dist(k, y),
   ret = r+c;
   return ret;
   //}
   //if (is_path(x, k, y)) {
   //   auto r = cost_dist(x, y);
   //   return r;
   //}
   //auto ret = numeric_limits<int64_t>::max();
   //const auto kx = cost_dist(k, x),
   //ky = cost_dist(k, y),
   //xy = cost_dist(x, y);
   //{//kxy
   //   auto c = 2*kx + xy;
   //   ret = min(ret, c);
   //}
   //{//kyx
   //   auto c = 2*ky + xy;
   //   ret = min(ret, c);
   //}
   //{//xyk
   //   //auto c = 2 * ky + xy;
   //   //ret = min(ret, c);
   //}
   //{//yxk
   //   //auto c = 2 * kx + xy;
   //   //ret = min(ret, c);
   //}
   //return ret;
}

int main() {
   ios_base::sync_with_stdio(0); cin.tie(0);
   
   cin >> n; for (int i = 1; i < n; i++) {
      int a, b, c; cin >> a >> b >> c;
      gr[a].push_back(make_pair(c, b)); gr[b].push_back(make_pair(c, a));
   }
   vi();
   propa();
   int q; cin >> q >> k;
   while(q--)
   {
      int x, y; cin >> x >> y;
      auto s = sol(x, y);
      cout << s << '\n';
   }
   return 0;
}