stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include <iostream>

#include <vector>

#define lim 100010



using namespace std;



typedef long long int LL;

struct edge { int to; LL cost; };



vector<edge> Graph[lim];

LL depth[lim];



void dfs (int v, int p, LL d) {

    depth[v] = d;

    for (int i = 0; i < Graph[v].size(); i++) {

        if (Graph[v][i].to == p) continue;

        dfs(Graph[v][i].to, v, d + Graph[v][i].cost);

    }

}



int main() {

    int N, a, b, c;

    int Q, K, x, y;

    edge tmp;



    cin >> N;



    for (int i = 0; i < N - 1; i++) {

        cin >> a >> b >> c;

        a--, b--;

        tmp.to = b; tmp.cost = c;

        Graph[a].push_back(tmp);

        tmp.to = a;

        Graph[b].push_back(tmp);

    }



    cin >> Q >> K;

    K--;



    dfs(K, -1, 0);



    for (int i = 0; i < Q; i++) {

        cin >> x >> y;

        x--; y--;

        cout << depth[x] + depth[y] << endl;

    }



    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.4442039729478817x):
#include <iostream>

#include <algorithm>

#include <vector>

#include <iomanip>

#include <cstdio>

#include <cmath>

#include <string>

#include <stack>

#include <queue>

#include <deque>

#include <map>

#include <set>



using namespace std;



typedef long long ll;

typedef pair<int, int> P;

const long long LINF = 1000000000000000018ll;

const int INF = 1000000009;

const int mod = 1000000007;



int v;

struct Edge {

  int dst;

  long long cost;

  Edge() {}

  Edge(int x, int y) : dst(x), cost(y) {}

};



vector<vector<Edge> > graph;

vector<long long> dijkstra(int start_v) {

  vector<long long> dist(v, 1000000000000000018ll);

  dist[start_v] = 0;

  priority_queue<pair<long long, int>, vector<pair<long long, int> >,

    greater<pair<long long, int> > > q;



  q.push(make_pair(0, start_v));



  while (!q.empty()) {

    pair<long long, int> t = q.top(); q.pop();

    int cur_v = t.second;

    for (int i = 0; i < graph[cur_v].size(); i++) {

      int next_v = graph[cur_v][i].dst;

      long long cost = graph[cur_v][i].cost;

      if (dist[next_v] > dist[cur_v] + cost) {

        dist[next_v] = dist[cur_v] + cost;

        q.push(make_pair(dist[next_v], next_v));

      }

    }

  }

  return dist;

}



int main() {

  cin.tie(0);

  ios::sync_with_stdio(false);

  cout << setprecision(20) << fixed;



  cin >> v;

  graph.assign(v, vector<Edge>());

  for (int i = 0; i < v-1; i++) {

    int src, dst, cost;

    cin >> src >> dst >> cost;

    src--; dst--;

    graph[src].push_back(Edge(dst, cost));

    graph[dst].push_back(Edge(src, cost));

  }

  int q, k;

  cin >> q >> k;

  vector<long long> dist = dijkstra(k-1);

  for (int i = 0; i < q; i++) {

    int x, y; cin >> x >> y;

    cout << dist[x-1] + dist[y-1] << endl;

  }

  return 0;

}
// Slower C++ solution:
#include <iostream>

#include <vector>

#include <cstdio>

#define lim 100010



using namespace std;



typedef long long int LL;

struct edge { int to; int cost; };



vector<edge> Graph[lim];

LL depth[lim];



void dfs (int v, int p, LL d) {

    depth[v] = d;

    for (int i = 0; i < Graph[v].size(); i++) {

        if (Graph[v][i].to == p) continue;

        dfs(Graph[v][i].to, v, d + Graph[v][i].cost);

    }

}



int main() {

    int N, a, b, c;

    int Q, K, x, y;

    edge tmp;



    scanf("%d", &N);

    // cin >> N;



    for (int i = 0; i < N - 1; i++) {

        // cin >> a >> b >> c;

        scanf("%d %d %d", &a, &b, &c);

        a--, b--;

        tmp.to = b; tmp.cost = c;

        Graph[a].push_back(tmp);

        tmp.to = a;

        Graph[b].push_back(tmp);

    }



    // cin >> Q >> K;

    scanf("%d %d", &Q, &K);

    K--;



    dfs(K, -1, 0);



    for (int i = 0; i < Q; i++) {

        // cin >> x >> y;

        scanf("%d %d", &x, &y);

        x--; y--;

        // cout << depth[x] + depth[y] << endl;

        printf("%lld\n", depth[x] + depth[y]);

    }



    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.427716402123387x):
#include <iostream>

#include <algorithm>

#include <vector>

#include <iomanip>

#include <cstdio>

#include <cmath>

#include <string>

#include <stack>

#include <queue>

#include <deque>

#include <map>

#include <set>



using namespace std;



typedef long long ll;

typedef pair<int, int> P;

const long long LINF = 1000000000000000018ll;

const int INF = 1000000009;

const int mod = 1000000007;



int v;

struct Edge {

  int dst;

  long long cost;

  Edge() {}

  Edge(int x, int y) : dst(x), cost(y) {}

};



vector<vector<Edge> > graph;

vector<long long> dijkstra(int start_v) {

  vector<long long> dist(v, 1000000000000000018ll);

  dist[start_v] = 0;

  priority_queue<pair<long long, int>, vector<pair<long long, int> >,

    greater<pair<long long, int> > > q;



  q.push(make_pair(0, start_v));



  while (!q.empty()) {

    pair<long long, int> t = q.top(); q.pop();

    int cur_v = t.second;

    for (int i = 0; i < graph[cur_v].size(); i++) {

      int next_v = graph[cur_v][i].dst;

      long long cost = graph[cur_v][i].cost;

      if (dist[next_v] > dist[cur_v] + cost) {

        dist[next_v] = dist[cur_v] + cost;

        q.push(make_pair(dist[next_v], next_v));

      }

    }

  }

  return dist;

}



int main() {

  cin.tie(0);

  ios::sync_with_stdio(false);

  cout << setprecision(20) << fixed;



  cin >> v;

  graph.assign(v, vector<Edge>());

  for (int i = 0; i < v-1; i++) {

    int src, dst, cost;

    cin >> src >> dst >> cost;

    src--; dst--;

    graph[src].push_back(Edge(dst, cost));

    graph[dst].push_back(Edge(src, cost));

  }

  int q, k;

  cin >> q >> k;

  vector<long long> dist = dijkstra(k-1);

  for (int i = 0; i < q; i++) {

    int x, y; cin >> x >> y;

    cout << dist[x-1] + dist[y-1] << endl;

  }

  return 0;

}
// Slower C++ solution:
#include <iostream>

#include <vector>

#include <utility>

#define lim 100010



using namespace std;



typedef long long int LL;

typedef pair<int, int> P;



vector<P> Graph[lim];

LL depth[lim];



void dfs (int v, int p, LL d) {

    depth[v] = d;

    for (int i = 0; i < Graph[v].size(); i++) {

        if (Graph[v][i].first == p) continue;

        dfs(Graph[v][i].first, v, d + Graph[v][i].second);

    }

}



int main() {

    int N, a, b, c;

    int Q, K, x, y;



    cin >> N;



    for (int i = 0; i < N - 1; i++) {

        cin >> a >> b >> c;

        a--, b--;

        Graph[a].push_back(P(b, c));

        Graph[b].push_back(P(a, c));

    }



    cin >> Q >> K;

    K--;



    dfs(K, -1, 0);



    for (int i = 0; i < Q; i++) {

        cin >> x >> y;

        x--; y--;

        cout << depth[x] + depth[y] << endl;

    }

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.444053813814172x):
#include <iostream>

#include <algorithm>

#include <vector>

#include <iomanip>

#include <cstdio>

#include <cmath>

#include <string>

#include <stack>

#include <queue>

#include <deque>

#include <map>

#include <set>



using namespace std;



typedef long long ll;

typedef pair<int, int> P;

const long long LINF = 1000000000000000018ll;

const int INF = 1000000009;

const int mod = 1000000007;



int v;

struct Edge {

  int dst;

  long long cost;

  Edge() {}

  Edge(int x, int y) : dst(x), cost(y) {}

};



vector<vector<Edge> > graph;

vector<long long> dijkstra(int start_v) {

  vector<long long> dist(v, 1000000000000000018ll);

  dist[start_v] = 0;

  priority_queue<pair<long long, int>, vector<pair<long long, int> >,

    greater<pair<long long, int> > > q;



  q.push(make_pair(0, start_v));



  while (!q.empty()) {

    pair<long long, int> t = q.top(); q.pop();

    int cur_v = t.second;

    for (int i = 0; i < graph[cur_v].size(); i++) {

      int next_v = graph[cur_v][i].dst;

      long long cost = graph[cur_v][i].cost;

      if (dist[next_v] > dist[cur_v] + cost) {

        dist[next_v] = dist[cur_v] + cost;

        q.push(make_pair(dist[next_v], next_v));

      }

    }

  }

  return dist;

}



int main() {

  cin.tie(0);

  ios::sync_with_stdio(false);

  cout << setprecision(20) << fixed;



  cin >> v;

  graph.assign(v, vector<Edge>());

  for (int i = 0; i < v-1; i++) {

    int src, dst, cost;

    cin >> src >> dst >> cost;

    src--; dst--;

    graph[src].push_back(Edge(dst, cost));

    graph[dst].push_back(Edge(src, cost));

  }

  int q, k;

  cin >> q >> k;

  vector<long long> dist = dijkstra(k-1);

  for (int i = 0; i < q; i++) {

    int x, y; cin >> x >> y;

    cout << dist[x-1] + dist[y-1] << endl;

  }

  return 0;

}
// Slower C++ solution:
// Name: Transit Tree Path

// Level: 2

// Category: Graph, 最短経路問題

// Note: 深さ優先探索



#include <iostream>

#include <vector>

#define MAX_V 100001



using namespace std;



struct edge { int to; long long cost; };



vector<edge> tree[MAX_V];

long long depth[MAX_V];



// v: 今いる頂点, p: v の親

void dfs(int v, int p, long long d) {

    depth[v] = d;

    for (int i = 0; i < tree[v].size(); i++) {

        edge e = tree[v][i];

        // 戻らないようにする処理

        if (e.to == p) { continue; }

        dfs(e.to, v, d + e.cost);

    }

}



int main() {

    int N, a, b, c;

    int Q, K, x, y;



    cin >> N;



    for (int i = 0; i < N-1; i++) {

        cin >> a >> b >> c;

        a--, b--;

        tree[a].push_back(edge{b, c});

        tree[b].push_back(edge{a, c});

    }



    cin >> Q >> K;

    dfs(K-1, -1, 0);



    for (int i = 0; i < Q; i++) {

        cin >> x >> y;

        x--; y--;

        cout << depth[x] + depth[y] << endl;

    }

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.4446665042797178x):
#include <iostream>

#include <algorithm>

#include <vector>

#include <iomanip>

#include <cstdio>

#include <cmath>

#include <string>

#include <stack>

#include <queue>

#include <deque>

#include <map>

#include <set>



using namespace std;



typedef long long ll;

typedef pair<int, int> P;

const long long LINF = 1000000000000000018ll;

const int INF = 1000000009;

const int mod = 1000000007;



int v;

struct Edge {

  int dst;

  long long cost;

  Edge() {}

  Edge(int x, int y) : dst(x), cost(y) {}

};



vector<vector<Edge> > graph;

vector<long long> dijkstra(int start_v) {

  vector<long long> dist(v, 1000000000000000018ll);

  dist[start_v] = 0;

  priority_queue<pair<long long, int>, vector<pair<long long, int> >,

    greater<pair<long long, int> > > q;



  q.push(make_pair(0, start_v));



  while (!q.empty()) {

    pair<long long, int> t = q.top(); q.pop();

    int cur_v = t.second;

    for (int i = 0; i < graph[cur_v].size(); i++) {

      int next_v = graph[cur_v][i].dst;

      long long cost = graph[cur_v][i].cost;

      if (dist[next_v] > dist[cur_v] + cost) {

        dist[next_v] = dist[cur_v] + cost;

        q.push(make_pair(dist[next_v], next_v));

      }

    }

  }

  return dist;

}



int main() {

  cin.tie(0);

  ios::sync_with_stdio(false);

  cout << setprecision(20) << fixed;



  cin >> v;

  graph.assign(v, vector<Edge>());

  for (int i = 0; i < v-1; i++) {

    int src, dst, cost;

    cin >> src >> dst >> cost;

    src--; dst--;

    graph[src].push_back(Edge(dst, cost));

    graph[dst].push_back(Edge(src, cost));

  }

  int q, k;

  cin >> q >> k;

  vector<long long> dist = dijkstra(k-1);

  for (int i = 0; i < q; i++) {

    int x, y; cin >> x >> y;

    cout << dist[x-1] + dist[y-1] << endl;

  }

  return 0;

}
// Slower C++ solution:
// Name: Transit Tree Path

// Level: 2

// Category: Graph, 最短経路問題

// Note: 深さ優先探索



#include <iostream>

#include <vector>

#include <stack>



#define MAX_V 100001



using namespace std;



struct edge { int to; long long cost; };

struct set {int v, p; long long d; };

vector<edge> tree[MAX_V];

long long depth[MAX_V];



void dfs(int v, int p, long long d) {

    stack<set> St;

    St.push(set{v, p, d});



    while (!St.empty()) {

        set cur = St.top(); St.pop();

        depth[cur.v] = cur.d;

        for (int i = 0; i < tree[cur.v].size(); i++) {

            edge e = tree[cur.v][i];

            if (e.to == cur.p) { continue; }

            St.push(set{e.to, cur.v, cur.d + e.cost});

        }

    }

}



int main() {

    int N, a, b, c;

    int Q, K, x, y;



    cin >> N;



    for (int i = 0; i < N-1; i++) {

        cin >> a >> b >> c;

        a--, b--;

        tree[a].push_back(edge{b, c});

        tree[b].push_back(edge{a, c});

    }



    cin >> Q >> K; K--;

    dfs(K, -1, 0);



    for (int i = 0; i < Q; i++) {

        cin >> x >> y;

        x--; y--;

        cout << depth[x] + depth[y] << endl;

    }

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.452335167620965x):
#include <iostream>

#include <algorithm>

#include <vector>

#include <iomanip>

#include <cstdio>

#include <cmath>

#include <string>

#include <stack>

#include <queue>

#include <deque>

#include <map>

#include <set>



using namespace std;



typedef long long ll;

typedef pair<int, int> P;

const long long LINF = 1000000000000000018ll;

const int INF = 1000000009;

const int mod = 1000000007;



int v;

struct Edge {

  int dst;

  long long cost;

  Edge() {}

  Edge(int x, int y) : dst(x), cost(y) {}

};



vector<vector<Edge> > graph;

vector<long long> dijkstra(int start_v) {

  vector<long long> dist(v, 1000000000000000018ll);

  dist[start_v] = 0;

  priority_queue<pair<long long, int>, vector<pair<long long, int> >,

    greater<pair<long long, int> > > q;



  q.push(make_pair(0, start_v));



  while (!q.empty()) {

    pair<long long, int> t = q.top(); q.pop();

    int cur_v = t.second;

    for (int i = 0; i < graph[cur_v].size(); i++) {

      int next_v = graph[cur_v][i].dst;

      long long cost = graph[cur_v][i].cost;

      if (dist[next_v] > dist[cur_v] + cost) {

        dist[next_v] = dist[cur_v] + cost;

        q.push(make_pair(dist[next_v], next_v));

      }

    }

  }

  return dist;

}



int main() {

  cin.tie(0);

  ios::sync_with_stdio(false);

  cout << setprecision(20) << fixed;



  cin >> v;

  graph.assign(v, vector<Edge>());

  for (int i = 0; i < v-1; i++) {

    int src, dst, cost;

    cin >> src >> dst >> cost;

    src--; dst--;

    graph[src].push_back(Edge(dst, cost));

    graph[dst].push_back(Edge(src, cost));

  }

  int q, k;

  cin >> q >> k;

  vector<long long> dist = dijkstra(k-1);

  for (int i = 0; i < q; i++) {

    int x, y; cin >> x >> y;

    cout << dist[x-1] + dist[y-1] << endl;

  }

  return 0;

}
// Slower C++ solution:
#include <iostream>

#include <vector>

#define MAX_V 100001



using namespace std;



struct edge { int to; long long cost; };



vector<edge> tree[MAX_V];

long long depth[MAX_V];



// v: 今いる頂点, p: v の親

void dfs(int v, int p, long long d) {

    depth[v] = d;

    for (int i = 0; i < tree[v].size(); i++) {

        edge e = tree[v][i];

        // 戻らないようにする処理

        if (e.to == p) { continue; }

        dfs(e.to, v, d + e.cost);

    }

}



int main() {

    int N, a, b, c;

    int Q, K, x, y;



    cin >> N;



    for (int i = 0; i < N-1; i++) {

        cin >> a >> b >> c;

        a--, b--;

        tree[a].push_back(edge{b, c});

        tree[b].push_back(edge{a, c});

    }



    cin >> Q >> K;

    dfs(K-1, -1, 0);



    for (int i = 0; i < Q; i++) {

        cin >> x >> y;

        x--; y--;

        cout << depth[x] + depth[y] << endl;

    }

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.4446665042797178x):
#include <iostream>

#include <algorithm>

#include <vector>

#include <iomanip>

#include <cstdio>

#include <cmath>

#include <string>

#include <stack>

#include <queue>

#include <deque>

#include <map>

#include <set>



using namespace std;



typedef long long ll;

typedef pair<int, int> P;

const long long LINF = 1000000000000000018ll;

const int INF = 1000000009;

const int mod = 1000000007;



int v;

struct Edge {

  int dst;

  long long cost;

  Edge() {}

  Edge(int x, int y) : dst(x), cost(y) {}

};



vector<vector<Edge> > graph;

vector<long long> dijkstra(int start_v) {

  vector<long long> dist(v, 1000000000000000018ll);

  dist[start_v] = 0;

  priority_queue<pair<long long, int>, vector<pair<long long, int> >,

    greater<pair<long long, int> > > q;



  q.push(make_pair(0, start_v));



  while (!q.empty()) {

    pair<long long, int> t = q.top(); q.pop();

    int cur_v = t.second;

    for (int i = 0; i < graph[cur_v].size(); i++) {

      int next_v = graph[cur_v][i].dst;

      long long cost = graph[cur_v][i].cost;

      if (dist[next_v] > dist[cur_v] + cost) {

        dist[next_v] = dist[cur_v] + cost;

        q.push(make_pair(dist[next_v], next_v));

      }

    }

  }

  return dist;

}



int main() {

  cin.tie(0);

  ios::sync_with_stdio(false);

  cout << setprecision(20) << fixed;



  cin >> v;

  graph.assign(v, vector<Edge>());

  for (int i = 0; i < v-1; i++) {

    int src, dst, cost;

    cin >> src >> dst >> cost;

    src--; dst--;

    graph[src].push_back(Edge(dst, cost));

    graph[dst].push_back(Edge(src, cost));

  }

  int q, k;

  cin >> q >> k;

  vector<long long> dist = dijkstra(k-1);

  for (int i = 0; i < q; i++) {

    int x, y; cin >> x >> y;

    cout << dist[x-1] + dist[y-1] << endl;

  }

  return 0;

}
// Slower C++ solution:
#include <iostream>

#include <vector>

#include <stack>



#define MAX_V 100001



using namespace std;



struct edge { int to; long long cost; };

struct sets {int v, p; long long d; };

vector<edge> tree[MAX_V];

long long depth[MAX_V];



void dfs(int v, int p, long long d) {

    stack<sets> St;

    St.push(sets{v, p, d});



    while (!St.empty()) {

        sets cur = St.top(); St.pop();

        depth[cur.v] = cur.d;

        for (int i = 0; i < tree[cur.v].size(); i++) {

            edge e = tree[cur.v][i];

            if (e.to == cur.p) { continue; }

            St.push(sets{e.to, cur.v, cur.d + e.cost});

        }

    }

}



int main() {

    int N, a, b, c;

    int Q, K, x, y;



    cin >> N;



    for (int i = 0; i < N-1; i++) {

        cin >> a >> b >> c;

        a--, b--;

        tree[a].push_back(edge{b, c});

        tree[b].push_back(edge{a, c});

    }



    cin >> Q >> K; K--;

    dfs(K, -1, 0);



    for (int i = 0; i < Q; i++) {

        cin >> x >> y;

        x--; y--;

        cout << depth[x] + depth[y] << endl;

    }

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.452335167620965x):
#include <iostream>

#include <algorithm>

#include <vector>

#include <iomanip>

#include <cstdio>

#include <cmath>

#include <string>

#include <stack>

#include <queue>

#include <deque>

#include <map>

#include <set>



using namespace std;



typedef long long ll;

typedef pair<int, int> P;

const long long LINF = 1000000000000000018ll;

const int INF = 1000000009;

const int mod = 1000000007;



int v;

struct Edge {

  int dst;

  long long cost;

  Edge() {}

  Edge(int x, int y) : dst(x), cost(y) {}

};



vector<vector<Edge> > graph;

vector<long long> dijkstra(int start_v) {

  vector<long long> dist(v, 1000000000000000018ll);

  dist[start_v] = 0;

  priority_queue<pair<long long, int>, vector<pair<long long, int> >,

    greater<pair<long long, int> > > q;



  q.push(make_pair(0, start_v));



  while (!q.empty()) {

    pair<long long, int> t = q.top(); q.pop();

    int cur_v = t.second;

    for (int i = 0; i < graph[cur_v].size(); i++) {

      int next_v = graph[cur_v][i].dst;

      long long cost = graph[cur_v][i].cost;

      if (dist[next_v] > dist[cur_v] + cost) {

        dist[next_v] = dist[cur_v] + cost;

        q.push(make_pair(dist[next_v], next_v));

      }

    }

  }

  return dist;

}



int main() {

  cin.tie(0);

  ios::sync_with_stdio(false);

  cout << setprecision(20) << fixed;



  cin >> v;

  graph.assign(v, vector<Edge>());

  for (int i = 0; i < v-1; i++) {

    int src, dst, cost;

    cin >> src >> dst >> cost;

    src--; dst--;

    graph[src].push_back(Edge(dst, cost));

    graph[dst].push_back(Edge(src, cost));

  }

  int q, k;

  cin >> q >> k;

  vector<long long> dist = dijkstra(k-1);

  for (int i = 0; i < q; i++) {

    int x, y; cin >> x >> y;

    cout << dist[x-1] + dist[y-1] << endl;

  }

  return 0;

}
// Slower C++ solution:
#include <iostream>

#include <vector>

#include <queue>



#define MAX_V 100001



using namespace std;



struct edge { int to; long long cost; };

struct sets { int v, p; long long d; };

vector<edge> tree[MAX_V];

long long depth[MAX_V];



void bfs(int v, int p, long long d) {

    queue<sets> q;

    q.push(sets{v, p, d});



    while (!q.empty()) {

        sets cur = q.front(); q.pop();

        depth[cur.v] = cur.d;

        for (int i = 0; i < tree[cur.v].size(); i++) {

            edge e = tree[cur.v][i];

            if (e.to == cur.p) { continue; }

            q.push(sets{e.to, cur.v, cur.d + e.cost});

        }

    }

}



int main() {

    int N, a, b, c;

    int Q, K, x, y;



    cin >> N;



    for (int i = 0; i < N-1; i++) {

        cin >> a >> b >> c;

        a--; b--;

        tree[a].push_back(edge{b, c});

        tree[b].push_back(edge{a, c});

    }



    cin >> Q >> K; K--;

    bfs(K, -1, 0);



    for (int i = 0; i < Q; i++) {

        cin >> x >> y;

        x--; y--;

        cout << depth[x] + depth[y] << endl;

    }

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.452660437445103x):
#include <iostream>

#include <algorithm>

#include <vector>

#include <iomanip>

#include <cstdio>

#include <cmath>

#include <string>

#include <stack>

#include <queue>

#include <deque>

#include <map>

#include <set>



using namespace std;



typedef long long ll;

typedef pair<int, int> P;

const long long LINF = 1000000000000000018ll;

const int INF = 1000000009;

const int mod = 1000000007;



int v;

struct Edge {

  int dst;

  long long cost;

  Edge() {}

  Edge(int x, int y) : dst(x), cost(y) {}

};



vector<vector<Edge> > graph;

vector<long long> dijkstra(int start_v) {

  vector<long long> dist(v, 1000000000000000018ll);

  dist[start_v] = 0;

  priority_queue<pair<long long, int>, vector<pair<long long, int> >,

    greater<pair<long long, int> > > q;



  q.push(make_pair(0, start_v));



  while (!q.empty()) {

    pair<long long, int> t = q.top(); q.pop();

    int cur_v = t.second;

    for (int i = 0; i < graph[cur_v].size(); i++) {

      int next_v = graph[cur_v][i].dst;

      long long cost = graph[cur_v][i].cost;

      if (dist[next_v] > dist[cur_v] + cost) {

        dist[next_v] = dist[cur_v] + cost;

        q.push(make_pair(dist[next_v], next_v));

      }

    }

  }

  return dist;

}



int main() {

  cin.tie(0);

  ios::sync_with_stdio(false);

  cout << setprecision(20) << fixed;



  cin >> v;

  graph.assign(v, vector<Edge>());

  for (int i = 0; i < v-1; i++) {

    int src, dst, cost;

    cin >> src >> dst >> cost;

    src--; dst--;

    graph[src].push_back(Edge(dst, cost));

    graph[dst].push_back(Edge(src, cost));

  }

  int q, k;

  cin >> q >> k;

  vector<long long> dist = dijkstra(k-1);

  for (int i = 0; i < q; i++) {

    int x, y; cin >> x >> y;

    cout << dist[x-1] + dist[y-1] << endl;

  }

  return 0;

}