Problem:
Score : 1400 points

Problem Statement

#nck {
width: 30px;
height: auto;
}

In the country there are N cities numbered 1 through N, which are connected by N-1 bidirectional roads. In terms of graph theory, there is a unique simple path connecting every pair of cities. That is, the N cities form a tree. Besides, if we view city 1 as the root of this tree, the tree will be a full binary tree (a tree is a full binary tree if and only if every non-leaf vertex in the tree has exactly two children). Roads are numbered 1 through N-1. The i-th road connects city i+1 and city a_i. When you pass through road i, the toll you should pay is v_i (if v_i is 0, it indicates the road does not require a toll).

A company in city 1 will give each employee a family travel and cover a large part of the tolls incurred. Each employee can design the travel by themselves. That is, which cities he/she wants to visit in each day and which city to stay at each night. However, there are some constraints. More details are as follows:

The travel must start and end at city 1. If there are m leaves in the tree formed by the cities, then the number of days in the travel must be m+1. At the end of each day, except for the last day, the employee must stay at some hotel in a leaf city. During the whole travel, the employee must stay at all leaf cities exactly once.

During the whole travel, all roads of the country must be passed through exactly twice.

The amount that the employee must pay for tolls by him/herself is the maximum total toll incurred in a single day during the travel, except the first day and the last day. The remaining tolls will be covered by the company.

Shik, as an employee of this company, has only one hope for his travel. He hopes that the amount he must pay for tolls by himself will be as small as possible. Please help Shik to design the travel which satisfies his hope.

Constraints

2 < N < 131,072

1 \leq a_i \leq i for all i

0 \leq v_i \leq 131,072

v_i is an integer

The given tree is a full binary tree

Input

The input is given from Standard Input in the following format:

N
a_1 v_1
a_2 v_2
:
a_{N-1} v_{N-1}

Output

Print an integer denoting the minimum amount Shik must pay by himself for tolls incurred during the travel.

Sample Input 1

7
1 1
1 1
2 1
2 1
3 1
3 1

Sample Output 1

4

There are 4 leaves in the tree formed by the cities (cities 4, 5, 6, and 7), so the travel must be 5 days long. There are 4! = 24 possible arrangements of the leaf cities to stay during the travel, but some of them are invalid. For example, (4,5,6,7) and (6,7,5,4) are valid orders, but (5,6,7,4) is invalid because the route passes 4 times through the road connecting city 1 and city 2. The figure below shows the routes of the travel for these arrangements.

For all valid orders, day 3 is the day with the maximum total incurred toll of 4, passing through 4 roads.

Sample Input 2

9
1 2
1 2
3 2
3 2
5 2
5 2
7 2
7 2

Sample Output 2

6

The following figure shows the route of the travel for one possible arrangement of the stayed cities for the solution. Note that the tolls incurred in the first day and the last day are always covered by the company.

Sample Input 3

15
1 2
1 5
3 3
4 3
4 3
6 5
5 4
5 3
6 3
3 2
11 5
11 3
13 2
13 1

Sample Output 3

15

Sample Input 4

3
1 0
1 0

Sample Output 4

0

Solution in C# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Linq;
using System.Collections.Generic;
using Debug = System.Diagnostics.Debug;
using StringBuilder = System.Text.StringBuilder;
using Number = System.Int64;
using static System.Math;
using P = Pair<long, long>;
namespace Program
{
    public class Solver
    {
        public void Solve()
        {
            var n = ri;
            var G = Enumerate(n, x => new List<KeyValuePair<int, int>>());
            for (int i = 0; i < n - 1; i++)
            {
                var a = ri - 1;
                var b = i + 1;
                var w = ri;
                G[a].Add(new KeyValuePair<int, int>(b, w));
            }
            Func<List<P>, List<P>, List<P>> g = (a, b) =>
            {
                var ret = new List<P>();
                var min = 1000000000000000;
                int i = 0, j = 0;
                while (i < a.Count && j < b.Count)
                {
                    var l = a[i];
                    var r = b[j];
                    if (min <= l.y) { i++; continue; }
                    if (min <= r.y) { j++; continue; }
                    if (l.CompareTo(r) <= 0) { i++; min = l.y; ret.Add(l); }
                    else { j++; min = r.y; ret.Add(r); }
                }
                while (i < a.Count)
                {
                    if (min <= a[i].y) i++;
                    else { min = a[i].y; ret.Add(a[i++]); }
                }
                while (j < b.Count)
                {
                    if (min <= b[j].y) j++;
                    else { min = b[j].y; ret.Add(b[j++]); }
                }

                return ret;
            };
            Func<int, int, long, List<P>> f = null;
            f = (prev, cur, x) =>
              {
                  if (G[cur].Count == 0) return new List<P>() { new P(0, 0) };
                  var l = f(cur, G[cur][0].Key, x);
                  var r = f(cur, G[cur][1].Key, x);
                  var u = G[cur][0].Value;
                  var v = G[cur][1].Value;
                  var a = new List<P>();
                  var b = new List<P>();
                  if (l.Count == 0 || r.Count == 0) return a;
                  for (int t = 0; t < 2; t++)
                  {

                      var j = 0; var k = 0;
                      while (j < l.Count)
                      {
                          while (k + 1 < r.Count && l[j].y + r[k + 1].x + u + v <= x) k++;
                          if (k < r.Count && l[j].y + r[k].x + u + v <= x) a.Add(new P(l[j].x + u, r[k].y + v));
                          j++;
                      }
                      Swap(ref l, ref r); Swap(ref u, ref v); Swap(ref a, ref b);
                  }

                  var ret = g(a, b);
                  //Debug.WriteLine($"[{cur}], {ret.AsJoinedString()}");
                  return ret;
              };

            {
                long l = -1, r = 100000000;
                while (r - l > 1)
                {
                    var m = (l + r) / 2;
                    if (f(-1, 0, m).Count != 0) r = m;
                    else l = m;
                }
                IO.Printer.Out.WriteLine(r);
            }
        }
        int ri => sc.Integer();
        long rl => sc.Long();
        double rd => sc.Double();
        string rs => sc.Scan();


        public IO.StreamScanner sc = new IO.StreamScanner(Console.OpenStandardInput());
        static T[] Enumerate<T>(int n, Func<int, T> f) { var a = new T[n]; for (int i = 0; i < n; ++i) a[i] = f(i); return a; }
        static public void Swap<T>(ref T a, ref T b) { var tmp = a; a = b; b = tmp; }
    }
}

#region main
static class Ex
{
    static public string AsString(this IEnumerable<char> ie) { return new string(System.Linq.Enumerable.ToArray(ie)); }
    static public string AsJoinedString<T>(this IEnumerable<T> ie, string st = " ") { return string.Join(st, ie); }
    static public void Main()
    {
        var solver = new Program.Solver();
        solver.Solve();
        Program.IO.Printer.Out.Flush();
    }
}
#endregion
#region Ex
namespace Program.IO
{
    using System.IO;
    using System.Text;
    using System.Globalization;
    public class Printer: StreamWriter
    {
        static Printer() { Out = new Printer(Console.OpenStandardOutput()) { AutoFlush = false }; }
        public static Printer Out { get; set; }
        public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } }
        public Printer(System.IO.Stream stream) : base(stream, new UTF8Encoding(false, true)) { }
        public Printer(System.IO.Stream stream, Encoding encoding) : base(stream, encoding) { }
        public void Write<T>(string format, T[] source) { base.Write(format, source.OfType<object>().ToArray()); }
        public void WriteLine<T>(string format, T[] source) { base.WriteLine(format, source.OfType<object>().ToArray()); }
    }
    public class StreamScanner
    {
        public StreamScanner(Stream stream) { str = stream; }
        public readonly Stream str;
        private readonly byte[] buf = new byte[1024];
        private int len, ptr;
        public bool isEof = false;
        public bool IsEndOfStream { get { return isEof; } }
        private byte read()
        {
            if (isEof) return 0;
            if (ptr >= len) { ptr = 0; if ((len = str.Read(buf, 0, 1024)) <= 0) { isEof = true; return 0; } }
            return buf[ptr++];
        }
        public char Char() { byte b = 0; do b = read(); while ((b < 33 || 126 < b) && !isEof); return (char)b; }

        public string Scan()
        {
            var sb = new StringBuilder();
            for (var b = Char(); b >= 33 && b <= 126; b = (char)read())
                sb.Append(b);
            return sb.ToString();
        }
        public string ScanLine()
        {
            var sb = new StringBuilder();
            for (var b = Char(); b != '\n'; b = (char)read())
                if (b == 0) break;
                else if (b != '\r') sb.Append(b);
            return sb.ToString();
        }
        public long Long()
        {
            if (isEof) return long.MinValue;
            long ret = 0; byte b = 0; var ng = false;
            do b = read();
            while (b != 0 && b != '-' && (b < '0' || '9' < b));
            if (b == 0) return long.MinValue;
            if (b == '-') { ng = true; b = read(); }
            for (; true; b = read())
            {
                if (b < '0' || '9' < b)
                    return ng ? -ret : ret;
                else ret = ret * 10 + b - '0';
            }
        }
        public int Integer() { return (isEof) ? int.MinValue : (int)Long(); }
        public double Double() { var s = Scan(); return s != "" ? double.Parse(s, CultureInfo.InvariantCulture) : double.NaN; }
        private T[] enumerate<T>(int n, Func<T> f)
        {
            var a = new T[n];
            for (int i = 0; i < n; ++i) a[i] = f();
            return a;
        }

        public char[] Char(int n) { return enumerate(n, Char); }
        public string[] Scan(int n) { return enumerate(n, Scan); }
        public double[] Double(int n) { return enumerate(n, Double); }
        public int[] Integer(int n) { return enumerate(n, Integer); }
        public long[] Long(int n) { return enumerate(n, Long); }
    }
}
#endregion
#region Compair
static public class Pair
{
    static public Pair<FT, ST> Create<FT, ST>(FT f, ST s) where FT : IComparable<FT> where ST : IComparable<ST>
    {
        return new Pair<FT, ST>(f, s);
    }
    static public Pair<FT, ST> Min<FT, ST>(Pair<FT, ST> p, Pair<FT, ST> q) where FT : IComparable<FT> where ST : IComparable<ST>
    {
        return (p.CompareTo(q) <= 0) ? p : q;
    }
    static public Pair<FT, ST> Max<FT, ST>(Pair<FT, ST> p, Pair<FT, ST> q) where FT : IComparable<FT> where ST : IComparable<ST>
    {
        return (p.CompareTo(q) >= 0) ? p : q;
    }
}
public struct Pair<FT, ST>: IComparable<Pair<FT, ST>> where FT : IComparable<FT> where ST : IComparable<ST>
{
    public FT x;
    public ST y;
    public Pair(FT f, ST s) : this() { x = f; y = s; }

    public int CompareTo(Pair<FT, ST> other)
    {
        var cmp = x.CompareTo(other.x);
        return cmp != 0 ? cmp : y.CompareTo(other.y);
    }
    public override string ToString() { return string.Format("[{0} {1}]", x, y); }
}
#endregion