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 Rust (1.42.0) (judge verdict: Accepted)

#[allow(unused_macros)]
macro_rules ! read_value {($ next : expr , ($ ($ t : tt ) ,* ) ) => {($ (read_value ! ($ next , $ t ) ) ,* ) } ; ($ next : expr , [$ t : tt ; $ len : expr ] ) => {(0 ..$ len ) . map (| _ | read_value ! ($ next , $ t ) ) . collect ::< Vec < _ >> () } ; ($ next : expr , chars ) => {read_value ! ($ next , String ) . chars () . collect ::< Vec < char >> () } ; ($ next : expr , usize1 ) => {read_value ! ($ next , usize ) - 1 } ; ($ next : expr , $ t : ty ) => {$ next () . parse ::<$ t > () . expect ("Parse error" ) } ; }
#[allow(unused_macros)]
macro_rules ! input_inner {($ next : expr ) => {} ; ($ next : expr , ) => {} ; ($ next : expr , $ var : ident : $ t : tt $ ($ r : tt ) * ) => {let $ var = read_value ! ($ next , $ t ) ; input_inner ! {$ next $ ($ r ) * } } ; }
#[allow(unused_macros)]
macro_rules ! input {(source = $ s : expr , $ ($ r : tt ) * ) => {let mut iter = $ s . split_whitespace () ; let mut next = || {iter . next () . unwrap () } ; input_inner ! {next , $ ($ r ) * } } ; ($ ($ r : tt ) * ) => {let stdin = std :: io :: stdin () ; let mut bytes = std :: io :: Read :: bytes (std :: io :: BufReader :: new (stdin . lock () ) ) ; let mut next = move || -> String {bytes . by_ref () . map (| r | r . unwrap () as char ) . skip_while (| c | c . is_whitespace () ) . take_while (| c |! c . is_whitespace () ) . collect () } ; input_inner ! {next , $ ($ r ) * } } ; }

use std::cmp::Ordering;
use std::ops::Index;
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct Edge {
    src: usize,
    dst: usize,
    weight: i32,
}
impl Ord for Edge {
    fn cmp(&self, other: &Self) -> Ordering {
        if self.weight != other.weight {
            self.weight.cmp(&other.weight)
        } else if self.src != other.src {
            self.src.cmp(&other.src)
        } else {
            self.dst.cmp(&other.dst)
        }
    }
}
impl PartialOrd for Edge {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
#[allow(dead_code)]
#[derive(Debug, Clone, PartialEq, Eq)]
struct Graph {
    g: Vec<Vec<Edge>>,
}
#[allow(dead_code)]
impl Graph {
    fn new(n: usize) -> Self {
        Graph { g: vec![vec![]; n] }
    }
    fn order(&self) -> usize {
        self.g.len()
    }
    fn add_directed_edge(&mut self, src: usize, dst: usize, weight: i32) {
        self.g[src].push(Edge { src, dst, weight })
    }
    fn add_undirected_edge(&mut self, src: usize, dst: usize, weight: i32) {
        self.add_directed_edge(src, dst, weight);
        self.add_directed_edge(dst, src, weight);
    }
}
impl Index<usize> for Graph {
    type Output = Vec<Edge>;
    fn index(&self, v: usize) -> &Self::Output {
        &self.g[v]
    }
}

#[allow(dead_code)]
/// predecessor subgraph by DFS
fn depth_first_tree(g: &Graph, source: usize) -> Graph {
    let mut visited = vec![false; g.order()];
    let mut stack = vec![];
    let mut tree = Graph::new(g.order());
    visited[source] = true;
    stack.push(source);
    while let Some(u) = stack.pop() {
        for e in &g[u] {
            let v = e.dst;
            if !visited[v] {
                visited[v] = true;
                stack.push(v);
                tree.add_directed_edge(u, v, e.weight);
            }
        }
    }
    tree
}

#[allow(unused_macros)]
macro_rules ! min {($ a : expr $ (, ) * ) => {{$ a } } ; ($ a : expr , $ b : expr , $ (, ) * ) => {{std :: cmp :: min ($ a , $ b ) } } ; ($ a : expr , $ ($ rest : expr ) ,+ $ (, ) * ) => {{std :: cmp :: min ($ a , min ! ($ ($ rest ) ,+ ) ) } } ; }
#[allow(unused_macros)]
macro_rules ! chmin {($ base : expr , $ ($ cmps : expr ) ,+ $ (, ) * ) => {{let cmp_min = min ! ($ ($ cmps ) ,+ ) ; if $ base > cmp_min {$ base = cmp_min ; true } else {false } } } ; }

fn main() {
    input! {
        n: usize,
        abc: [(usize, usize, i32); n - 1],
        q: usize,
        k: usize,
        xy: [(usize, usize); q],
    }
    let mut g = Graph::new(n);
    for (a, b, c) in abc {
        g.add_undirected_edge(a - 1, b - 1, c);
    }

    let tree = depth_first_tree(&g, k - 1);
    let mut dist = vec![std::i64::MAX; n];
    let mut stack = vec![];
    dist[k - 1] = 0;
    stack.push(k - 1);
    while let Some(u) = stack.pop() {
        for e in &tree[u] {
            if dist[u] < std::i64::MAX {
                chmin!(dist[e.dst], dist[u] + e.weight as i64);
            }
            stack.push(e.dst);
        }
    }

    for i in 0..q {
        let ret = dist[xy[i].0 - 1] + dist[xy[i].1 - 1];
        println!("{}", ret);
    }
}