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 C# (.NET Core 3.1.201) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace AtCoder.D
{
    public class Program
    {
        public static void Main() { var r = GetResult(); Debug.WriteLine(r); Console.Write(r); }

        private static object GetResult()
        {
            var N = ReadLong();
            var dist = Enumerable.Range(0, (int)N)
                .ToDictionary(x => x, y => new List<Path>());
            for (var i = 0; i < N - 1; i++)
            {
                var (a, b, c) = Read3Longs();
                a--; b--; // インデックス変換

                dist[(int)a].Add(new Path { From = a, To = b, Dist = c });
                dist[(int)b].Add(new Path { From = b, To = a, Dist = c });
            }

            var (Q, K) = Read2Longs();
            K--;//インデックス変換
            var distK = new long[N];
            distK[K] = 0;
            var q = new Queue<Path>();
            var removeIndexes = new List<int>();
            foreach (var item in dist[(int)K])
            {
                q.Enqueue(item);
                removeIndexes.Add(dist[(int)K].IndexOf(item));
            }

            foreach (var remove in removeIndexes.OrderByDescending(x => x))
            {
                dist[(int)K].RemoveAt(remove);
            }

            while (q.Count > 0)
            {
                var dq = q.Dequeue();

                distK[dq.To] = distK[dq.From] + dq.Dist;
                var removes = new List<int>();
                foreach (var item in dist[(int)dq.To])
                {
                    if (distK[item.To] != 0)
                    {
                        removes.Add(dist[(int)dq.To].IndexOf(item));
                        continue;
                    }
                    q.Enqueue(item);
                }

                foreach (var remove in removes.OrderByDescending(x => x))
                {
                    dist[(int)dq.To].RemoveAt(remove);
                }
            }

            var sb = new StringBuilder();
            for (var i = 0; i < Q; i++)
            {
                var (x, y) = Read2Longs();
                x--; y--;//インデックス変換
                var d = distK[x] + distK[y];
                sb.AppendLine(d.ToString());
            }

            return sb.ToString().Trim();
        }

        private class Path
        {
            public long From { get; set; }
            public long To { get; set; }
            public long Dist { get; set; }
        }

        #region Console.Read

        public static string ReadText() { return Console.ReadLine(); }
        public static List<string> ReadTexts() { return Console.ReadLine().Split(' ').ToList(); }
        public static long ReadLong() { return long.Parse(Console.ReadLine()); }
        public static (long, long) Read2Longs() { var ls = ReadLongs(); return (ls[0], ls[1]); }
        public static (long, long, long) Read3Longs() { var ls = ReadLongs(); return (ls[0], ls[1], ls[2]); }
        public static (long, long, long, long) Read4Longs() { var ls = ReadLongs(); return (ls[0], ls[1], ls[2], ls[3]); }
        public static (long, long, long, long, long) Read5Longs() { var ls = ReadLongs(); return (ls[0], ls[1], ls[2], ls[3], ls[4]); }
        public static List<long> ReadLongs() { return Console.ReadLine().Split(' ').Select(x => long.Parse(x)).ToList(); }

        #endregion
    }
}