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.15.1) (judge verdict: Accepted)

use std::ops::{Index, IndexMut};
use std::cmp::{Ordering};
use std::collections::BinaryHeap;
// use std::clone::Clone;

fn getline() -> String{
    let mut res = String::new();
    std::io::stdin().read_line(&mut res).ok();
    res
}

macro_rules! split {
    ($x: expr) => {
        ($x).trim().split(' ').collect();
    }
}

macro_rules! parse {
    ($x: expr) => {
        ($x).parse().unwrap();
    }
}

fn printvec<T>(v: &Vec<T>) where T: std::fmt::Display {
    for e in v {
        print!("{} ", e);
    }
    println!();
}

type Cost = i64;

struct Edge {
    to: usize,
    cost: Cost,
}

impl std::clone::Clone for Edge {
    fn clone(&self) -> Edge { Edge{to: self.to, cost: self.cost} }
}

impl Ord for Edge {
    fn cmp(&self, other: &Edge) -> Ordering {
        (-self.cost).cmp(&(-other.cost))
    }
}

impl PartialOrd for Edge {
    fn partial_cmp(&self, other: &Edge) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Eq for Edge {}

impl PartialEq for Edge {
    fn eq(&self, other: &Edge) -> bool {
        self.cost == other.cost
    }
}

struct Graph {
    adj: Vec<Vec<Edge>>,
}

impl Index<usize> for Graph {
    type Output = Vec<Edge>;

    fn index(&self, i: usize) -> &Vec<Edge> {
        &self.adj[i]
    }
}

impl IndexMut<usize> for Graph {
    fn index_mut<'a>(&'a mut self, i: usize) -> &'a mut Vec<Edge> {
        &mut self.adj[i]
    }
}

impl Graph {

    fn new(n: usize) -> Graph{
        Graph {
            adj: vec![vec![]; n],
        }
    }

    fn size(&self) -> usize{
        self.adj.capacity()
    }

    fn add_edge(&mut self, from: usize, to_: usize, cost_: Cost) {
        self.adj[from].push(Edge{to: to_, cost: cost_});
    }

    fn add_uedge(&mut self, from: usize, to_: usize, cost_: Cost) {
        self.add_edge(from, to_, cost_);
        self.add_edge(to_, from, cost_);
    }

    fn get_shortest_path(&self, from: usize) -> (Vec<Cost>, Vec<usize>) {
        let n = self.size();
        
        let mut dist = vec![std::i64::MAX; n];
        let mut pre = vec![n as usize; n];
        let mut heap = BinaryHeap::new();
        heap.push(Edge{to: from, cost: 0});
        dist[from] = 0;
        println!();
        while !heap.is_empty() {
            match heap.pop() {
                None => {
                    assert!(true);
                }
                Some(p) => {
                    for e in &(*self)[p.to] {
                        if p.cost+e.cost >= dist[e.to] {
                            continue;
                        }
                        heap.push(Edge{to: e.to, cost: p.cost+e.cost});
                        dist[e.to] = p.cost+e.cost;
                        pre[e.to] = p.to;
                    }
                }
            }
        }
        
        (dist, pre)
    }
}

// fn main() {
//     let s = getline();
//     let iv: Vec<_> = split!(s);
//     let n: usize = parse!(iv[0]);
//     let m: usize = parse!(iv[1]);
//     let mut g = Graph::new(n);
//     for _ in 0..m {
//         let s = getline();
//         let iv: Vec<_> = split!(s);
//         let a: usize = parse!(iv[0]);
//         let b: usize = parse!(iv[1]);
//         let c: Cost = parse!(iv[2]);
//         g.add_uedge(a-1, b-1, c);
//     }

//     let (dist, path) = g.get_shortest_path(0);
//     match dist[n-1] {
//         std::i64::MAX => {
//             println!("{}", -1);
//         }
//         _ => {
//             let mut sta = Vec::new();
//             sta.push(n-1 as usize);
//             let mut p = n-1;
//             while p != 0 {
//                 p = path[p];
//                 sta.push(p);
//             }
//             while let Some(top) = sta.pop() {
//                 print!("{}", top+1);
//                 if sta.len() >= 1 {
//                     print!(" ");
//                 }
//             }
//             println!();
//         }
//     }
// }

fn main() {
    let s = getline();
    
    let iv: Vec<_> = split!(s);
    let n: usize = parse!(iv[0]);
    let mut g = Graph::new(n);
    for _ in 0..(n-1) {
        let s = getline();
        let iv: Vec<_> = split!(s);
        let a: usize = parse!(iv[0]);
        let b: usize = parse!(iv[1]);
        let c: i64 = parse!(iv[2]);
        g.add_uedge(a-1, b-1, c);
    }
    let s = getline();
    let iv: Vec<_> = split!(s);
    let q: usize = parse!(iv[0]);
    let k__: usize = parse!(iv[1]);
    let k = k__-1;
    let mut dist = vec![0 as i64; n];

    fn dfs(g: &Graph, mut dist: Vec<i64>, p: usize, pre: usize) -> Vec<i64> {
        for e in &g[p] {
            if e.to == pre {
                continue;
            }
            dist[e.to] = dist[p]+e.cost;
            dist = dfs(&g, dist, e.to, p);
        }
        dist
    }

    dist = dfs(&g, dist, k, n);

    for _ in 0..q {
        let s = getline();
        let iv: Vec<_> = split!(s);
        let a: usize = parse!(iv[0]);
        let b: usize = parse!(iv[1]);
        println!("{}", dist[a-1]+dist[b-1]);
    }
}

// fn main() {
//     // let mut hoge = BinaryHeap::new();
//     // hoge.push(-1);
//     // hoge.push(1);
//     // hoge.push(100);
//     // hoge.push(5);
//     // while let Some(x) = hoge.pop() {
//     //     println!("{}", x);
//     // }

//     let mut v = vec![-4, 5, 3,3];
//     let hoge:Vec<_> = v.into_iter().map(|c| c*2).collect();
//     printvec(&hoge);
// }


// fn main() {
//     fn f(mut v: Vec<i32>) -> Vec<i32> {
//         v[1] = 100;
//         v
//     }
//     let v = vec![1,2,3];
//     let v = f(v);
//     println!("{}",v[1]);
// }