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 Java8 (OpenJDK 1.8.0) (judge verdict: Time Limit Exceeded)

import java.util.*;

public class Main{
//     5
// 1 2 1
// 1 3 1
// 2 4 1
// 3 5 1
// 3 1
// 2 4
// 2 3
// 4 5
    public static void main(String[] args){
        ArrayList<Node> nodes=new ArrayList<Node>();
        Scanner sc=new Scanner(System.in);
        int n=Integer.parseInt(sc.next());
        int a,b;
        long c;
        for(int i=0;i<n;i++) nodes.add(new Node(i));
        for(int i=0;i<n-1;i++){
            a=Integer.parseInt(sc.next())-1;
            b=Integer.parseInt(sc.next())-1;
            c=Long.parseLong(sc.next());
            nodes.get(a).edges.add(new Edge(b,c));
            nodes.get(b).edges.add(new Edge(a,c));
        }
        int q=Integer.parseInt(sc.next());
        int k=Integer.parseInt(sc.next())-1;
        long afterK[]=Dijkstra.dijkstra(nodes, k);
        for(Node node:nodes) node.reset();
        int x,y;
        for(int j=0;j<q;j++){
            x=Integer.parseInt(sc.next())-1;
            y=Integer.parseInt(sc.next())-1;
            System.out.println(Dijkstra.dijkstra(nodes, x)[k]+afterK[y]);
            for(Node node:nodes){
                node.reset();
                // System.out.println("id:"+node.id+" value:"+node.value);
            }           
            // for(int i=0;i<n;i++) System.out.println(afterK[i]);
        }
        sc.close();
    }
    static class Dijkstra{
        public static long[] dijkstra(ArrayList<Node> nodes, int st){
            return dijkstra(nodes, st, -1);
        }   
        public static long[] dijkstra(ArrayList<Node> nodes, int st, int ed){
            long[] res=new long[nodes.size()];
            Node stNode=nodes.get(st);
            PriorityQueue<Node> pq=new PriorityQueue<Node>(new DistanceComparator());
            for(Node n:nodes){
                pq.add(n);
                res[n.id]=Long.MAX_VALUE;
            }
            pq.remove(stNode);
            stNode.value=0;
            res[st]=0;
            pq.add(stNode);
            Node seeing, next;
            long newValue;
            while(pq.size()>0){
                seeing=pq.poll();           
                if(seeing.value==Long.MAX_VALUE) return res;
                if(seeing.id==ed) return res;               
                for(Edge e:seeing.edges){
                    newValue=seeing.value+e.cost;
                    next=nodes.get(e.id);
                    if(newValue<next.value){
                        res[e.id]=newValue;
                        if(pq.remove(next)){
                            next.value=newValue;
                            next.prev=seeing;
                            pq.add(next);
                        }
                    }
                }
            }
            return res;
        }
    }
    static class Node{
        int id;
        long value;
        Node prev;
        ArrayList<Edge> edges;
        public Node(int id){
            this.id=id;
            this.value=Long.MAX_VALUE;
            edges=new ArrayList<Edge>();
        }
        public void reset(){
            this.value=Long.MAX_VALUE;
            this.prev=null;
        }
        @Override public boolean equals(Object o){
            if(! (o instanceof Node)) return false;
            Node n=(Node) o;
            if(n.id==id) return true;
            else return false;
        }
        @Override public int hashCode(){
            return id;
        }
    }

    static class Edge{
        int id;;
        long cost;
        public Edge(int id, long cost){
            this.id=id;
            this.cost=cost;
        }
    }

    static class Pair{
        int id1;
        int id2;
        public Pair(int id1, int id2){
            this.id1=id1;
            this.id2=id2;
        }
        @Override public boolean equals(Object o){
            if(! (o instanceof Pair)) return false;
            Pair p=(Pair) o;
            if((p.id1==id1 && p.id2==id2) || (p.id1==id2 && p.id2==id1)) return true;
            else return false;
        }
        @Override public int hashCode(){
            int res=17;
            res=((res*31+id1)*31+id2)+((res*31+id2)*31+id1);
            return 0;
        }
    }

    static class DistanceComparator implements Comparator<Node>{
        @Override public int compare(Node a, Node b){
            if(a.value<b.value) return -1;
            else if(a.value>b.value) return 1;
            else return 0;
        }
    }
}