stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

 

long long n;

vector<long long> v(100005);

map<long long,vector<pair<long long,long long>>> mp;

bool used[100005];

 

void dfs(long long s,long long dist){

        used[s]=true;

        v[s]=dist;



        for(auto i:mp[s]){

            if(!used[i.first])

                dfs(i.first,dist+i.second);

        }



}

 

int main(){

    cin>>n;

    long long a,b,c;

    for(long long i=0;i<n-1;i++){

        cin>>a>>b>>c;

        a--,b--;

        mp[a].push_back(make_pair(b,c));

        mp[b].push_back(make_pair(a,c));

    }

    long long k,q;

    cin>>q>>k;

    k--;

    

 

    dfs(k,0);

 

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

        long long x,y;

        cin>>x>>y;

        x--,y--;

      

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

    }

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;

 

class Dijkstra {

public:

    struct edge { long long v, dist; };

 

    struct state {

        long long v, cost;

        bool operator>(const state s) const { return cost > s.cost; }

    };

 

    const long long INF = (1LL << 60);

    long long N;

    vector< vector<edge> > E;

 

    Dijkstra(long long n): N(n), E(n) {}

 

    //有効グラフの時はこっち。u→vに距離dで結ぶ

    void add_directed_edge(long long u, long long v, long long d) {

        E[u].push_back((edge) { v, d });

    }

 

    //無向グラフの時はこっち。uとvを双方向に距離dで結ぶ

    void add_undirected_edge(long long u, long long v, long long d) {

        E[u].push_back((edge) { v, d });

        E[v].push_back((edge) { u, d });

    }

 

    //Sを始点として、他の頂点への最短経路を探す

    vector<long long> shortest_path(long long S) {

        vector<long long> dp(E.size(), INF);

        priority_queue<state, vector<state>, greater<state> > q;

        q.push((state) { S, 0 });

        while(!q.empty()) {

            long long v = q.top().v, cost = q.top().cost;

            q.pop();

            if(dp[v] <= cost) continue;

            dp[v] = cost;

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

            long long nv = E[v][i].v, ncost = cost + E[v][i].dist;

            if(dp[nv] > ncost) q.push((state) { nv, ncost });

            }

        }

        return dp;

    }

};

 

 

int main(){

    long long n;

    cin>>n;

    long long a,b,c;

    Dijkstra d(n);

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

        cin>>a>>b>>c;

        a--,b--;

        d.add_undirected_edge(a,b,c);

    }

    long long q,k;

    cin>>q>>k;

    k--;

    vector<long long> ans=d.shortest_path(k);

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

        long long x,y;

        cin>>x>>y;

        x--,y--;



        

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

    }

    

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

#include<iomanip>

#include<numeric>



using namespace std;

using ll = long long;

using ull = unsigned long long;

constexpr int mo = 1e9+7;

constexpr int  mod = mo;

constexpr int inf = 1<<30;

constexpr ll infl = 1ll<<60;

vector<pair<int,int>> E[100050];

vector<ll> dist(100050,infl);

void dfs(int u,int pre){

    for(auto v : E[u]){

        if(v.second == pre)continue;

        if(dist[v.second] > dist[u] + v.first){

            dist[v.second] = dist[u] + v.first;

            dfs(v.second,u);

        }

    }

}

int main(){

    int n;

    cin>>n;

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

        int a,b,c;

        cin>>a>>b>>c;

        a--;b--;

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

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

    }

    int q,k;

    cin>>q>>k;

    k--;

    dist[k] = 0ll;

    dfs(k,-1);

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

        int u,v;

        cin>>u>>v;

        u--;v--;

        cout << dist[u] + dist[v] << endl;

    }

    return 0;

}




// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>



using namespace std;

using ll = long long;

using ull = unsigned long long;

constexpr int inf = 1<<30;

constexpr int mo = 1e9+7;

constexpr ll infl = 1ll<<60;



int main(){

    cin.tie(nullptr);

    ios::sync_with_stdio(false);

    

    int n;

    cin>>n;

    vector<pair<int,int>> E[100050];

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

        int a,b;ll c;

        cin>>a>>b>>c;

        a--;b--;

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

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

    }

    int Q,k;

    cin>>Q>>k;

    k--;

    queue<int> q;

    q.push(k);

    vector<ll> dist(n,infl);

    dist[k] = 0;

    while(!q.empty()){

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

        for(auto & v : E[cur]){

            if(dist[cur] + v.second < dist[v.first]){

                dist[v.first] = dist[cur] + v.second;

                q.push(v.first);

            }

        }

    }

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

        int x,y;

        cin>>x>>y;

        x--;y--;

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

    }

    return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

#define rep(i,n)for(int i=0;i<(n);i++)

using namespace std;

typedef long long ll;

typedef pair<int,int>P;



vector<P>E[200000];

ll d[200000];

int par[20][200000];



struct LCA{

public:

	vector<vector<int> > g;

	const int MAX_LOG = 22;

	vector<vector<int> > lcc;

	vector<int> dep;

	void init2(){

		int n = g.size();

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

			for (int j = 0; j < n; j++){

				if (lcc[i][j] == -1){

					lcc[i + 1][j] = -1;

					continue;

				}

				lcc[i + 1][j] = lcc[i][lcc[i][j]];

			}

		}

	}

	int lca(int a, int b){

		if (dep[a] < dep[b]){

			swap(a, b);

		}

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

			if (((dep[a] - dep[b]) >> i) & 1){

				a = lcc[i][a];

			}

		}

		if (a == b){

			return a;

		}

		for (int i = MAX_LOG - 1; i >= 0; i--){

			if (lcc[i][a] != lcc[i][b]){

				a = lcc[i][a];

				b = lcc[i][b];

			}

		}

		return lcc[0][a];

	}

	inline void dfs(int b, int pr = -1, int d = 0){

		for (auto &i : g[b]){

			if (i == pr)continue;

			dfs(i, b, d + 1);

		}

		dep[b] = d;

		lcc[0][b] = pr;

	}

	void init(vector<vector<int> > &tree, int root = 0){

		g = tree;

		lcc.resize(MAX_LOG, vector<int>(g.size(), 0));

		dep.resize(g.size());

		dfs(root);

		init2();

	}

};

void dfs(int v,int p,ll d1){

	d[v]=d1;par[0][v]=p;

	for(P u:E[v]){

		if(u.second!=p)dfs(u.second,v,d1+u.first);

	}

}

LCA G;

ll dist(int x,int y){

	return d[x]+d[y]-d[G.lca(x,y)]*2;

}

int main(){

	int n;scanf("%d",&n);

	vector<vector<int>>F(n);

	rep(i,n-1){

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

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

		F[a].push_back(b);F[b].push_back(a);

	}

	G.init(F);

	dfs(0,-1,0);

	int q,k;scanf("%d%d",&q,&k);k--;

	rep(i,q){

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

		printf("%lld\n",dist(x,k)+dist(k,y));

	}

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

#define rep(i,n)for(int i=0;i<(n);i++)

using namespace std;

typedef pair<int,int>P;

typedef long long ll;



vector<P>E[100000];

ll d[100000];

void dfs(int v,int p){

	for(P u:E[v]){

		if(u.second!=p){

			d[u.second]=d[v]+u.first;dfs(u.second,v);

		}

	}

}

int main(){

	int n;scanf("%d",&n);

	rep(i,n-1){

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

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

	}

	int q,k;scanf("%d%d",&q,&k);k--;

	dfs(k,-1);

	rep(i,q){

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

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

	}

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

#define rep(i,n)for(int i=0;i<(n);i++)

using namespace std;

typedef long long ll;

typedef pair<int,int>P;



vector<P>E[200000];

ll d[200000],q[200000];

int par[25][200000];



void dfs(int v,int p,ll d1,ll d2){

	d[v]=d1;q[v]=d2;par[0][v]=p;

	for(P u:E[v]){

		if(u.second!=p)dfs(u.second,v,d1+1,d2+u.first);

	}

}

int lca(int u,int v){

	if(d[u]>d[v])swap(u,v);

	rep(i,22){

		if((d[v]-d[u])>>i&1)v=par[i][v];

	}

	if(u==v)return u;

	for(int i=21;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 x,int y){

	return q[x]+q[y]-q[lca(x,y)]*2;

}

int main(){

	int n;scanf("%d",&n);

	rep(i,n-1){

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

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

	}

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

	for(int i=1;i<22;i++)rep(j,n){

		if(par[i-1][j]==-1)par[i][j]=-1;

		else par[i][j]=par[i-1][par[i-1][j]];

	}

	int q,k;scanf("%d%d",&q,&k);k--;

	rep(i,q){

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

		printf("%lld\n",dist(x,k)+dist(k,y));

	}

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

#define rep(i,n)for(int i=0;i<(n);i++)

using namespace std;

typedef pair<int,int>P;

typedef long long ll;



vector<P>E[100000];

ll d[100000];

void dfs(int v,int p){

	for(P u:E[v]){

		if(u.second!=p){

			d[u.second]=d[v]+u.first;dfs(u.second,v);

		}

	}

}

int main(){

	int n;scanf("%d",&n);

	rep(i,n-1){

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

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

	}

	int q,k;scanf("%d%d",&q,&k);k--;

	dfs(k,-1);

	rep(i,q){

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

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

	}

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}

// Optimized solution to the same problem (faster):
#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;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}

// Optimized solution to the same problem (faster):
#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;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}

// Optimized solution to the same problem (faster):
#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;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
// 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;

}

// Optimized solution to the same problem (faster):
#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;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
// 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;

}

// Optimized solution to the same problem (faster):
#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;

}

// Fastest known solution for this problem: