Problem:
F: リレー / Relay
問題文
湖に浮かぶ $N$ 個の小島からなるビワコという村がある．
ビワコ村には $N-1$ 本の簡単な作りの橋がある．
島には $0$ から $N-1$ まで，橋には $0$ から $N-2$ までの番号が付けられている．
$i$ 番の橋は $i+1$ 番の島と $p_i$ 番の島を直接つなぎ，長さは $w_i$ である．
村人はどの島の間もいくつかの橋を通って相互に移動できるようになっている．
ある村人の提案により，ビワコ村でリレー大会が開催されることとなった．
しかし，ビワコ村には閉路がなくトラックを用意できないため，
現在ある橋を $1$ つだけ掛け替えることによって閉路を作ろうと考えた．
この操作によって用意できる閉路のうち，長さが最大となるものの長さを求めなさい．
入力
$N$
$p_0 \ w_0$
$\vdots$
$p_{n-2} \ w_{n-2}$
制約
$2 \leq N \leq 100000$
$0 \leq p_i \leq N-1$
$1 \leq w_i \leq 1000$
全て整数
全ての島と島の間が到達可能である
出力
答えを $1$ 行で出力せよ．
サンプル
各サンプルを図示すると次のようになる．
サンプル入力1
5
0 1
0 2
0 3
0 4
サンプル出力1
9
サンプル入力2
12
0 6
1 1
0 3
3 4
0 2
5 1
6 1
0 2
8 1
9 1
10 2
サンプル出力2
19
サンプル入力3
2
0 1
サンプル出力3
1

Submitted solutions:

code_snippet: // AOJ #2770 Relay
// 2025.4.21

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

#define gc() getchar_unlocked()

int Cin() {
	int n = 0, c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

int main(){
    int N = Cin();
    vector<vector<pair<int,int>>> adj(N);
    vector<tuple<int,int,int>> edges(N-1);
    for(int i = 0; i < N-1; i++){
        int v = Cin(), w = Cin();
        int u = i + 1;
        edges[i] = {u, v, w};
        adj[u].emplace_back(v, w);
        adj[v].emplace_back(u, w);
    }

    vector<int> parent(N, -1), pw(N, 0);
    vector<vector<int>> children(N);
    vector<int> idx(N, 0), post;
    post.reserve(N);
    vector<int> stk;
    stk.reserve(N);

    parent[0] = -2;
    stk.push_back(0);
    while(!stk.empty()){
        int u = stk.back();
        if(idx[u] < (int)adj[u].size()){
            auto [v, w] = adj[u][idx[u]++];
            if(parent[u] == v) continue;
            parent[v] = u;
            pw[v] = w;
            children[u].push_back(v);
            stk.push_back(v);
        } else {
            post.push_back(u);
            stk.pop_back();
        }
    }

    vector<ll> down1(N,0), down2(N,0), down3(N,0), sub_dia(N,0);
    vector<int> d1id(N,-1), d2id(N,-1), d3id(N,-1);
    vector<ll> child_dia1(N,0), child_dia2(N,0);
    vector<int> cd1id(N,-1);

    for(int u: post){
        for(int v: children[u]){
            ll h = down1[v] + pw[v];
            if(h > down1[u]){
                down3[u] = down2[u]; d3id[u] = d2id[u];
                down2[u] = down1[u]; d2id[u] = d1id[u];
                down1[u] = h, d1id[u] = v;
            } else if(h > down2[u]){
                down3[u] = down2[u]; d3id[u] = d2id[u];
                down2[u] = h, d2id[u] = v;
            } else if(h > down3[u]){
                down3[u] = h, d3id[u] = v;
            }
        }
        ll best1 = 0, best2 = 0;
        int best1idx = -1;
        for(int v: children[u]){
            ll cd = sub_dia[v];
            if(cd > best1){
                best2 = best1;
                best1 = cd;
                best1idx = v;
            } else if(cd > best2) best2 = cd;
        }
        child_dia1[u] = best1;
        child_dia2[u] = best2;
        cd1id[u] = best1idx;
        sub_dia[u] = max(best1, down1[u] + down2[u]);
    }

    vector<ll> up(N,0), dout(N,0);
    stk.clear();
    stk.push_back(0);
    while(!stk.empty()){
        int u = stk.back(); stk.pop_back();
        for(int v: children[u]){
            ll best_h = (d1id[u] != v ? down1[u]
                         : (d2id[u] != v ? down2[u]
                                         : down3[u]));
            ll c1, c2;
            if(d1id[u] != v){
                c1 = down1[u];
                c2 = (d2id[u] != v ? down2[u] : down3[u]);
            } else {
                c1 = down2[u];
                c2 = down3[u];
            }
            ll cross = c1 + c2;
            ll bcd = (cd1id[u] != v ? child_dia1[u] : child_dia2[u]);

            ll best = dout[u];
            best = max(best, bcd);
            best = max(best, cross);
            best = max(best, up[u] + best_h);
            dout[v] = best;

            ll up_ex = max(up[u], best_h);
            up[v] = up_ex + pw[v];

            stk.push_back(v);
        }
    }

    ll ans = 0;
    for(auto [u, v, w] : edges){
        if(parent[v] == u) ans = max(ans, max(sub_dia[v], dout[v]) + w);
        else ans = max(ans, max(sub_dia[u], dout[u]) + w);
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 24816
final_rank: 2

code_snippet: #include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdlib>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>

/* template start */

using i64 = std::int_fast64_t;
using u64 = std::uint_fast64_t;

#define rep(i, a, b) for (i64 i = (a); (i) < (b); (i)++)
#define all(i) i.begin(), i.end()

#ifdef LOCAL
#define debug(...)                                                    \
  std::cerr << "LINE: " << __LINE__ << "  [" << #__VA_ARGS__ << "]:", \
      debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

void debug_out() { std::cerr << std::endl; }

template <typename Head, typename... Tail>
void debug_out(Head h, Tail... t) {
  std::cerr << " " << h;
  if (sizeof...(t) > 0) std::cout << " :";
  debug_out(t...);
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, std::pair<T1, T2> pa) {
  return os << pa.first << " " << pa.second;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, std::vector<T> vec) {
  for (std::size_t i = 0; i < vec.size(); i++)
    os << vec[i] << (i + 1 == vec.size() ? "" : " ");
  return os;
}

template <typename T1, typename T2>
inline bool chmax(T1& a, T2 b) {
  return a < b && (a = b, true);
}

template <typename T1, typename T2>
inline bool chmin(T1& a, T2 b) {
  return a > b && (a = b, true);
}

template <typename Num>
constexpr Num mypow(Num a, u64 b, Num id = 1) {
  if (b == 0) return id;
  Num x = id;
  while (b > 0) {
    if (b & 1) x *= a;
    a *= a;
    b >>= 1;
  }
  return x;
}

template <typename T>
std::vector<std::pair<std::size_t, T>> enumerate(const std::vector<T>& data) {
  std::vector<std::pair<std::size_t, T>> ret;
  for (std::size_t index = 0; index < data.size(); index++)
    ret.emplace_back(index, data[index]);
  return ret;
}

/* template end */

int main() {
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);

  i64 n;
  std::cin>>n;

  using P=std::pair<i64,i64>;

  std::vector<std::vector<P>> graph(n);

  i64 ans=0;

  rep(i,1,n){
    i64 p,w;
    std::cin>>p>>w;

    chmax(ans,w);

    graph[i].emplace_back(p,w);
    graph[p].emplace_back(i,w);
  }

  std::vector<i64> arch(n,0),path_root(n,0);

  auto dfs1=[&](auto&& f,i64 now,i64 par)->void{
    arch[now] = 0;
    path_root[now] = 0;

    i64 first=0,second=0;

    for(auto itr = graph[now].begin();itr!=graph[now].end();){
      if(itr->first == par){
        itr = graph[now].erase(itr);
        continue;
      }

      const auto& [e,w] = *itr;

      f(f,e,now);
      chmax(arch[now],arch[e]);

      if(path_root[e] + w > first){
        second = first;
        first = path_root[e]+w;
      }else if(path_root[e] + w > second){
        second = path_root[e]+w;
      }

      itr++;
    }

    path_root[now] = first;
    chmax(arch[now],first+second);
  };

  dfs1(dfs1,0,-1);

  debug(arch);
  debug(path_root);

  auto dfs2=[&](auto&& f,i64 now,i64 par,i64 pw,i64 parch,i64 ppath)->void{
    if(par!=-1){
      chmax(ans,arch[now]+pw);
      chmax(ans,parch + pw);
    }

    debug(now,par,pw,parch,ppath);

    if(graph[now].empty())return;

    i64 m = graph[now].size();
    std::vector<i64> lfirst(m),lsecond(m),rfirst(m),rsecond(m);
    std::vector<i64> lmax(m),rmax(m);

    lfirst[0] = 0;
    lsecond[0] = 0;
    lmax[0]=0;
    rep(i,1,m){
      const auto& [e,w] = graph[now][i-1];
      lmax[i] = std::max(lmax[i-1],arch[e]);
      lfirst[i] = lfirst[i-1];
      lsecond[i] = lsecond[i-1];
      if(path_root[e] + w > lfirst[i-1]){
        lsecond[i] = lfirst[i-1];
        lfirst[i] = path_root[e]+w;
      }else if(path_root[e] + w > lsecond[i-1]){
        lfirst[i] = lfirst[i-1];
        lsecond[i] = path_root[e]+w;
      }
    }

    rfirst[m-1] = ppath + pw;
    rsecond[m-1] = 0;
    rmax[m-1] = parch;
    for(i64 i = m-2;i>=0;i--){
      const auto& [e,w] = graph[now][i+1];
      rmax[i] = std::max(rmax[i+1],arch[e]);
      rfirst[i] = rfirst[i+1];
      rsecond[i] = rsecond[i+1];
      if(path_root[e] + w > rfirst[i+1]){
        rsecond[i] = rfirst[i+1];
        rfirst[i] = path_root[e]+w;
      }else if(path_root[e]+w > rsecond[i+1]){
        rfirst[i] = rfirst[i+1];
        rsecond[i] = path_root[e]+w;
      }
    }

    if(now == 2){
      debug(rfirst);
      debug(rsecond);
    }

    rep(i,0,m){
      const auto& [e,w] = graph[now][i];
      i64 narch = std::max(lmax[i],rmax[i]);
      i64 npath = std::max(lfirst[i],rfirst[i]);
      std::vector<i64> tmp = {lfirst[i],lsecond[i],rfirst[i],rsecond[i]};
      std::sort(all(tmp),std::greater<i64>());
      chmax(narch,tmp[0]+tmp[1]);

      f(f,e,now,w,narch,npath);
    }
  };

  dfs2(dfs2,0,-1,0,0,0);

  std::cout<<ans<<"\n";

  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 58620
final_rank: 9

code_snippet: #include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdlib>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>

/* template start */

using i64 = std::int_fast64_t;
using u64 = std::uint_fast64_t;

#define rep(i, a, b) for (i64 i = (a); (i) < (b); (i)++)
#define all(i) i.begin(), i.end()

#ifdef LOCAL
#define debug(...)                                                    \
  std::cerr << "LINE: " << __LINE__ << "  [" << #__VA_ARGS__ << "]:", \
      debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

void debug_out() { std::cerr << std::endl; }

template <typename Head, typename... Tail>
void debug_out(Head h, Tail... t) {
  std::cerr << " " << h;
  if (sizeof...(t) > 0) std::cout << " :";
  debug_out(t...);
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, std::pair<T1, T2> pa) {
  return os << pa.first << " " << pa.second;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, std::vector<T> vec) {
  for (std::size_t i = 0; i < vec.size(); i++)
    os << vec[i] << (i + 1 == vec.size() ? "" : " ");
  return os;
}

template <typename T1, typename T2>
inline bool chmax(T1& a, T2 b) {
  return a < b && (a = b, true);
}

template <typename T1, typename T2>
inline bool chmin(T1& a, T2 b) {
  return a > b && (a = b, true);
}

template <typename Num>
constexpr Num mypow(Num a, u64 b, Num id = 1) {
  if (b == 0) return id;
  Num x = id;
  while (b > 0) {
    if (b & 1) x *= a;
    a *= a;
    b >>= 1;
  }
  return x;
}

template <typename T>
std::vector<std::pair<std::size_t, T>> enumerate(const std::vector<T>& data) {
  std::vector<std::pair<std::size_t, T>> ret;
  for (std::size_t index = 0; index < data.size(); index++)
    ret.emplace_back(index, data[index]);
  return ret;
}

/* template end */

int main() {
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);

  i64 n;
  std::cin>>n;

  using P=std::pair<i64,i64>;

  std::vector<std::vector<P>> graph(n);

  i64 ans=0;

  rep(i,1,n){
    i64 p,w;
    std::cin>>p>>w;

    chmax(ans,w);

    graph[i].emplace_back(p,w);
    graph[p].emplace_back(i,w);
  }

  std::vector<i64> arch(n,0),path_root(n,0);

  auto dfs1=[&](auto&& f,i64 now,i64 par)->void{
    arch[now] = 0;
    path_root[now] = 0;

    i64 first=0,second=0;

    for(auto itr = graph[now].begin();itr!=graph[now].end();){
      if(itr->first == par){
        itr = graph[now].erase(itr);
        continue;
      }

      const auto& [e,w] = *itr;

      f(f,e,now);
      chmax(arch[now],arch[e]);

      if(path_root[e] + w > first){
        second = first;
        first = path_root[e]+w;
      }else if(path_root[e] + w > second){
        second = path_root[e]+w;
      }

      itr++;
    }

    path_root[now] = first;
    chmax(arch[now],first+second);
  };

  dfs1(dfs1,0,-1);

  auto dfs2=[&](auto&& f,i64 now,i64 par,i64 pw,i64 parch,i64 ppath)->void{
    if(par!=-1){
      chmax(ans,arch[now]+pw);
      chmax(ans,parch + pw);
    }

    if(graph[now].empty())return;

    i64 m = graph[now].size();
    std::vector<i64> lfirst(m),lsecond(m),rfirst(m),rsecond(m);
    std::vector<i64> lmax(m),rmax(m);

    lfirst[0] = 0;
    lsecond[0] = 0;
    lmax[0]=0;
    rep(i,1,m){
      const auto& [e,w] = graph[now][i-1];
      lmax[i] = std::max(lmax[i-1],arch[e]);
      if(path_root[e] + w > lfirst[i-1]){
        lsecond[i] = lfirst[i-1];
        lfirst[i] = path_root[e]+w;
      }else if(path_root[e] + w > lsecond[i-1]){
        lfirst[i] = lfirst[i-1];
        lsecond[i] = path_root[e]+w;
      }
    }

    rfirst[m-1] = ppath + pw;
    rsecond[m-1] = 0;
    rmax[m-1] = parch;
    for(i64 i = m-2;i>=0;i--){
      const auto& [e,w] = graph[now][i+1];
      rmax[i] = std::max(rmax[i+1],arch[e]);
      if(path_root[e] + w > rfirst[i+1]){
        rsecond[i] = rfirst[i+1];
        rfirst[i] = path_root[e]+w;
      }else if(path_root[e]+w > rsecond[i+1]){
        rfirst[i] = rfirst[i+1];
        rsecond[i] = path_root[e]+w;
      }
    }

    rep(i,0,m){
      const auto& [e,w] = graph[now][i];
      i64 narch = std::max(lmax[i],rmax[i]);
      i64 npath = std::max(lfirst[i],rfirst[i]);
      std::vector<i64> tmp = {lfirst[i],lsecond[i],rfirst[i],rsecond[i]};
      std::sort(all(tmp),std::greater<i64>());
      chmax(narch,tmp[0]+tmp[1]);

      f(f,e,now,w,narch,npath);
    }
  };

  dfs2(dfs2,0,-1,0,0,0);

  std::cout<<ans<<"\n";

  return 0;
}
accuracy: 0.2542372881355932
time_ms: 30
memory_kb: 16220
final_rank: 20

code_snippet: #include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdlib>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>

/* template start */

using i64 = std::int_fast64_t;
using u64 = std::uint_fast64_t;

#define rep(i, a, b) for (i64 i = (a); (i) < (b); (i)++)
#define all(i) i.begin(), i.end()

#ifdef LOCAL
#define debug(...)                                                    \
  std::cerr << "LINE: " << __LINE__ << "  [" << #__VA_ARGS__ << "]:", \
      debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

void debug_out() { std::cerr << std::endl; }

template <typename Head, typename... Tail>
void debug_out(Head h, Tail... t) {
  std::cerr << " " << h;
  if (sizeof...(t) > 0) std::cout << " :";
  debug_out(t...);
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, std::pair<T1, T2> pa) {
  return os << pa.first << " " << pa.second;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, std::vector<T> vec) {
  for (std::size_t i = 0; i < vec.size(); i++)
    os << vec[i] << (i + 1 == vec.size() ? "" : " ");
  return os;
}

template <typename T1, typename T2>
inline bool chmax(T1& a, T2 b) {
  return a < b && (a = b, true);
}

template <typename T1, typename T2>
inline bool chmin(T1& a, T2 b) {
  return a > b && (a = b, true);
}

template <typename Num>
constexpr Num mypow(Num a, u64 b, Num id = 1) {
  if (b == 0) return id;
  Num x = id;
  while (b > 0) {
    if (b & 1) x *= a;
    a *= a;
    b >>= 1;
  }
  return x;
}

template <typename T>
std::vector<std::pair<std::size_t, T>> enumerate(const std::vector<T>& data) {
  std::vector<std::pair<std::size_t, T>> ret;
  for (std::size_t index = 0; index < data.size(); index++)
    ret.emplace_back(index, data[index]);
  return ret;
}

/* template end */

int main() {
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);

  i64 n;
  std::cin>>n;

  using P=std::pair<i64,i64>;

  std::vector<std::vector<P>> graph(n);

  i64 ans=0;

  rep(i,1,n){
    i64 p,w;
    std::cin>>p>>w;

    chmax(ans,w);

    graph[i].emplace_back(p,w);
    graph[p].emplace_back(i,w);
  }

  std::vector<i64> arch(n,0),path_root(n,0);

  auto dfs1=[&](auto&& f,i64 now,i64 par)->void{
    arch[now] = 0;
    path_root[now] = 0;

    i64 first=0,second=0;

    for(auto itr = graph[now].begin();itr!=graph[now].end();){
      if(itr->first == par){
        itr = graph[now].erase(itr);
        continue;
      }

      const auto& [e,w] = *itr;

      f(f,e,now);
      chmax(arch[now],arch[e]);

      if(path_root[e] + w > first){
        second = first;
        first = path_root[e]+w;
      }else if(path_root[e] + w > second){
        second = path_root[e]+w;
      }

      itr++;
    }

    path_root[now] = first;
    chmax(arch[now],first+second);
  };

  dfs1(dfs1,0,-1);

  auto dfs2=[&](auto&& f,i64 now,i64 par,i64 pw,i64 parch,i64 ppath)->void{
    if(par!=-1){
      chmax(ans,arch[now]+pw);
      chmax(ans,parch + pw);
    }

    if(graph[now].empty())return;

    i64 m = graph[now].size();
    std::vector<i64> lfirst(m),lsecond(m),rfirst(m),rsecond(m);
    std::vector<i64> lmax(m),rmax(m);

    lfirst[0] = 0;
    lsecond[0] = 0;
    lmax[0]=0;
    rep(i,1,m){
      const auto& [e,w] = graph[now][i-1];
      lmax[i] = std::max(lmax[i-1],arch[e]);
      if(path_root[e] + w > lfirst[i-1]){
        lsecond[i] = lfirst[i-1];
        lfirst[i] = path_root[e]+w;
      }else if(path_root[e] + w > lsecond[i-1]){
        lfirst[i] = lfirst[i-1];
        lsecond[i] = path_root[e]+w;
      }
    }

    rfirst[m-1] = ppath + pw;
    rsecond[m-1] = 0;
    rmax[m-1] = parch;
    for(i64 i = m-2;i>=0;i--){
      const auto& [e,w] = graph[now][i+1];
      rmax[i] = std::max(rmax[i+1],arch[e]);
      if(path_root[e] + w > rfirst[i+1]){
        rsecond[i] = rfirst[i+1];
        rfirst[i] = path_root[e]+w;
      }else if(path_root[e]+w > rsecond[i+1]){
        rfirst[i] = rfirst[i+1];
        rsecond[i] = path_root[e]+w;
      }
    }

    rep(i,0,m){
      const auto& [e,w] = graph[now][i];
      i64 narch = std::max(lmax[i],rmax[i]);
      i64 npath = std::max(lfirst[i],rfirst[i]);
      std::vector<i64> tmp = {lfirst[i],lsecond[i],rfirst[i],rsecond[i]};
      std::sort(all(tmp),std::greater<i64>());
      chmax(narch,tmp[0]+tmp[1]);

      f(f,e,now,w,narch,npath);
    }
  };

  dfs2(dfs2,0,-1,0,0,0);

  std::cout<<ans<<"\n";

  return 0;
}
accuracy: 0.2542372881355932
time_ms: 30
memory_kb: 16184
final_rank: 19

code_snippet: #include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <algorithm>
#include <bitset>
#include <complex>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <cassert>
#include <functional>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(...) ;
#else
#define debug(...) cerr << __LINE__ << " : " << #__VA_ARGS__ << " = " << _tostr(__VA_ARGS__) << endl;

template<typename T>
ostream &operator<<(ostream &out, const vector<T> &v);

template<typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template<typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}

void _tostr_rec(ostringstream &oss) {
  oss << "\b\b \b";
}

template<typename Head, typename... Tail>
void _tostr_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << head << ", ";
  _tostr_rec(oss, forward<Tail>(tail)...);
}

template<typename... T>
string _tostr(T &&... args) {
  ostringstream oss;
  int size = sizeof...(args);
  if (size > 1) oss << "{";
  _tostr_rec(oss, forward<T>(args)...);
  if (size > 1) oss << "}";
  return oss.str();
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 300000000 //3e8
#define LLINF 2000000000000000000LL //2e18
#define SIZE 200010

vector<pair<int, int>> G[SIZE];
pair<int, int> lE[SIZE][3];
int cSize[SIZE];

pair<int, int> dfs1(int now) {
  cSize[now] = 1;
  for (auto p : G[now]) {
    auto res = dfs1(p.first);
    cSize[now] += res.second;
    int e = max(res.first, p.second);
    lE[now][2] = max(lE[now][2], {e, p.first});
    if (lE[now][1] < lE[now][2]) swap(lE[now][1], lE[now][2]);
    if (lE[now][0] < lE[now][1]) swap(lE[now][0], lE[now][1]);
  }

  return {lE[now][0].first, cSize[now]};
}

int ans = 0;

pair<pair<int, int>, int> dfs2(int now, int L) { // {max dist, max (dist + w)}
  int D = 0, DW = -INF, W = -INF, DD = -INF;

  for (auto p : G[now]) {
    int to = p.first;
    int l = lE[now][0].second == to ? lE[now][1].first : lE[now][0].first;
    auto res = dfs2(p.first, max({L, l, p.second}));

    int d = res.first.first + p.second;
    int dw = res.first.second + p.second;
    int w = max(p.second, res.second);

    ans = max(ans, D + d + L);
    ans = max(ans, D + dw);
    ans = max(ans, DW + d);
    ans = max(ans, DD + w);

    DW = max({DW, dw, d + W, D + w});
    DD = max(DD, D + d);
    D = max(D, d);
    W = max(W, w);
  }

  debug(now, ans, L, D, DW, W);

  return {{D, DW}, W};
}

int inEdge[SIZE] = {};

int main() {
  int N, sumW = 0;

  scanf("%d", &N);

  for (int i = 1; i < N; i++) {
    int p, w;
    scanf("%d%d", &p, &w);
    G[p].push_back({i, w});
    sumW += w;
    inEdge[p]++;
    inEdge[i]++;
  }

  int counter = 0;

  for (int i = 0; i < N; i++) {
    counter += inEdge[i] == 1;
    if (inEdge[i] > 2) counter = INF;
  }

  if (counter == 2) {
    printf("%d\n", sumW);
    return 0;
  }

  dfs1(0);
  dfs2(0, -INF);

  cout << ans << endl;

  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 17808
final_rank: 1

code_snippet: #if 1
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack>
#include <array>
#include <deque>
#include <algorithm>
#include <utility>
#include <cstdint>
#include <functional>
#include <iomanip>
#include <numeric>
#include <assert.h>
#include <bitset>
#include <list>
#include <cmath>
//#include <atcoder/all>

auto& in = std::cin;
auto& out = std::cout;
#define all_range(C) std::begin(C), std::end(C)
const double PI = 3.141592653589793238462643383279502884197169399375105820974944;


template<typename T, typename U>
std::enable_if_t<std::rank<T>::value == 0> fill_all(T& arr, const U& v) {
    arr = v;
}
template<typename ARR, typename U>
std::enable_if_t<std::rank<ARR>::value != 0> fill_all(ARR& arr, const U& v) {
    for (auto& i : arr) {
        fill_all(i, v);
    }
}

std::map<int, int> graph[100000];
int N;
bool used_v[100000];
int parent[100000];
int32_t D[100000];
void dfs(int v, int p, int32_t depth) {
    parent[v] = p;
    D[v] = depth;
    for (auto& next : graph[v]) {
        if (next.first == p) { continue; }
        dfs(next.first, v, depth + next.second);
    }
}

int32_t maxdp[100000];
int32_t maxdep(int v, int p) {
    if (maxdp[v] != -1) { return maxdp[v]; }
    maxdp[v] = D[v];
    for (auto& next : graph[v]) {
        if (next.first == p) { continue; }
        if (used_v[next.first]) { continue; }
        maxdp[v] = std::max(maxdp[v], maxdep(next.first, v));
    }
    return maxdp[v];
}

int main()
{
    using std::endl;
    using std::cout;
    in.sync_with_stdio(false);
    out.sync_with_stdio(false);
    in.tie(nullptr);
    out.tie(nullptr);

    in >> N;
    for (size_t i = 0; i < N-1; i++)
    {
        int b, l;
        in >> b >> l;
        graph[i + 1].insert({ b, l });
        graph[b].insert({ i + 1, l });
    }

    dfs(0, -1, 0);
    int maxa = std::max_element(D, D + N) - D;
    dfs(maxa, -1, 0);
    int maxb = std::max_element(D, D + N) - D;

    int32_t used_max = 0;
    int v = maxb;
    while (true) {
        used_v[v] = true;
        if (parent[v] == -1) { break; }
        if (used_max < graph[v][parent[v]]) {
            used_max = graph[v][parent[v]];
        }

        v = parent[v];
    }

    int32_t not_used_max = 0;
    for (size_t i = 0; i < N; i++)
    {
        for (auto& edge : graph[i]) {
            if (used_v[i] && used_v[edge.first]) { continue; }
            if (not_used_max < edge.second) {
                not_used_max = edge.second;
            }
        }
    }
    int32_t res = D[maxb] + not_used_max;

    //graph[used_max_a].erase(used_max_b);
    //graph[used_max_b].erase(used_max_a);

    //fill_all(D, -1);
    //dfs(used_max_a, -1, 0);
    //dfs(std::max_element(D, D + N) - D, -1, 0);
    //res = std::max(res, (*std::max_element(D, D + N)) + used_max);

    //fill_all(D, -1);
    //dfs(used_max_b, -1, 0);
    //dfs(std::max_element(D, D + N) - D, -1, 0);
    //res = std::max(res, (*std::max_element(D, D + N)) + used_max);

    fill_all(maxdp, -1);
    v = maxb;
    used_max = 0;
    while (true) {
        if (parent[v] == -1) { break; }
        used_max = std::max(used_max, graph[v][parent[v]]);
        res = std::max(res, maxdep(parent[v], -1) + used_max);
        v = parent[v];
    }

    dfs(maxb, -1, 0);
    fill_all(maxdp, -1);
    v = maxa;
    used_max = 0;
    while (true) {
        if (parent[v] == -1) { break; }
        used_max = std::max(used_max, graph[v][parent[v]]);
        res = std::max(res, maxdep(parent[v], -1) + used_max);
        v = parent[v];
    }

    out << res << endl;

    return 0;
}
#endif
accuracy: 1
time_ms: 120
memory_kb: 23148
final_rank: 8

code_snippet: //
// Created by yamunaku on 2020/10/23.
//

#include <bits/stdc++.h>
//#include <atcoder/all>

using namespace std;
//using namespace atcoder;

#define rep(i, n) for(int i = 0; i < (n); i++)
#define repl(i, l, r) for(int i = (l); i < (r); i++)
#define per(i, n) for(int i = ((n)-1); i >= 0; i--)
#define perl(i, l, r) for(int i = ((r)-1); i >= (l); i--)
#define all(x) (x).begin(),(x).end()
#define MOD9 998244353
#define MOD1 1000000007
#define IINF 1000000000
#define LINF 1000000000000000000
#define SP <<" "<<
#define CYES cout<<"Yes"<<endl
#define CNO cout<<"No"<<endl
#define CFS cin.tie(0);ios::sync_with_stdio(false)
#define CST(x) cout<<fixed<<setprecision(x)

using ll = long long;
using ld = long double;
using vi = vector<int>;
using mti = vector<vector<int>>;
using vl = vector<ll>;
using mtl = vector<vector<ll>>;
using pi = pair<int, int>;
using pl = pair<ll, ll>;
template<typename T>
using heap = priority_queue<T, vector<T>, function<bool(const T, const T)>>;

vector<pair<int, int>> p;
vector<vector<pair<int, int>>> ch;

struct status {
    int top;
    int ans;
};

pair<int, int> get2(pair<int, int> pp, int x) {
    if (x > pp.first) return {x, pp.first};
    else if (x > pp.second) return {pp.first, x};
    else return pp;
}

vector<status> s;

int answer = 0;

status dfs(int x) {
    status ans = {0, 0};
    pair<int, int> top2 = {0, 0};
    for (auto &p : ch[x]) {
        auto ret = dfs(p.first);
        ret.top += p.second;
        top2 = get2(top2, ret.top);
        ans.ans = max(ans.ans, ret.ans);
        answer = max(answer, ret.ans + p.second);
    }
    ans.top = max(ans.top, top2.first);
    ans.ans = max(ans.ans, top2.first + top2.second);
    s[x] = ans;
    return s[x];
}

void zendfs(int x, int ans, int top) {
    int sz = ch[x].size();
    vector<pair<int, int>> pl(sz + 1, {0, 0});
    vector<pair<int, int>> pr(sz + 1, {0, 0});
    vi ansl(sz + 1, ans), ansr(sz + 1, ans);
    rep(i, sz) {
        pl[i + 1] = get2(pl[i], s[ch[x][i].first].top + ch[x][i].second);
        ansl[i + 1] = max(ansl[i], s[ch[x][i].first].ans);
    }
    per(i, sz) {
        pr[i] = get2(pr[i + 1], s[ch[x][i].first].top + ch[x][i].second);
        ansr[i] = max(ansr[i + 1], s[ch[x][i].first].ans);
    }
    rep(i, sz) {
        auto pp = pl[i];
        pp = get2(pp, pr[i + 1].first);
        pp = get2(pp, pr[i + 1].second);
        pp = get2(pp, top);
        int k = max(max(ansl[i], ansr[i + 1]), pp.first + pp.second);
//        cout << ch[x][i].first SP  pp.first SP pp.second SP ansl[i] SP ansr[i] SP k << endl;
        answer = max(answer, k + ch[x][i].second);
        zendfs(ch[x][i].first, k, pp.first + ch[x][i].second);
    }
}

vector<vector<pair<int, int>>> e;

void indfs(int x, int prnt, int &c) {
    int now = c;
//    cout << x SP c << endl;
    c++;
    for (auto &nx : e[x]) {
        if (nx.first == prnt) continue;
        p[c] = {now, nx.second};
        ch[now].emplace_back(c, nx.second);
        indfs(nx.first, x, c);
    }
}

int main() {
    //CFS;
    int n;
    cin >> n;
    p = vector<pair<int, int>>(n, {0, 0});
    ch = vector<vector<pair<int, int>>>(n);
    s = vector<status>(n);
    e = vector<vector<pair<int, int>>>(n);
    rep(i, n - 1) {
        int to, w;
        cin >> to >> w;
        e[i + 1].emplace_back(to, w);
        e[to].emplace_back(i + 1, w);
    }
    int idx = 0;
    indfs(0, 0, idx);
    dfs(0);
    zendfs(0, 0, 0);
    cout << answer << endl;
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 37336
final_rank: 5

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n % mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }

const int max_n = 1 << 18;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}

const int mn = 1 << 18;
struct edge {
	int to; int cost;
};
using Data = P;
vector<edge> G[mn];
vector<int> ids[mn];
vector<Data> memo[mn];
vector<int> costs[mn];
int root;

Data merge(Data a, Data b) {
	Data res;
	//
	res.first = max(a.first, b.first);
	res.second = max({ a.second,b.second,a.first + b.first });
	//
	return res;
}

int ans = 0;
Data dfs(int id, int fr) {
	Data res;
	//
	//initialize
	res = { 0,0 };
	//
	for (edge e : G[id]) {
		if (e.to == fr)continue;
		Data nex = dfs(e.to, id);

		//calc ans
		ans = max(ans, e.cost + nex.second);
		//
		//update with edge
		nex.first += e.cost;
		nex.second = max(nex.second, nex.first);
		//
		res = merge(res, nex);
		ids[id].push_back(e.to);
		memo[id].push_back(nex);
		costs[id].push_back(e.cost);
	}
	//
	//update for return
	//
	return res;
}
void invdfs(int id, int fr, Data pre) {
	vector<Data> v;
	for (Data d : memo[id])v.push_back(d);
	if (fr >= 0)v.push_back(pre);
	int len = v.size();
	//
	//calcurate id's ans
	//
	vector<Data> le(len + 1);
	vector<Data> ri(len + 1);
	//
	Data init_c = { 0,0 };
	//
	le[0] = init_c;
	rep(i, len) {
		le[i + 1] = merge(le[i], v[i]);
	}
	ri[len] = init_c;
	per(i, len) {
		ri[i] = merge(ri[i + 1], v[i]);
	}
	rep(i, ids[id].size()) {
		int to = ids[id][i];
		Data d = merge(le[i], ri[i + 1]);
		ans = max(ans, costs[id][i] + d.second);
		//
		//update for return
		d.first += costs[id][i];
		d.second = max(d.first, d.second);
		//
		invdfs(to, id, d);
	}
}
void yaru() {
	dfs(root, -1);
	invdfs(root, -1, { 0,0 });
}
void solve() {
	int n; cin >> n;
	rep(i, n - 1) {
		int p, w; cin >> p >> w;
		G[i + 1].push_back({ p,w });
		G[p].push_back({ i + 1,w });
	}
	yaru();
	cout << ans << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(15);
	//init_f();
	//init();
	//expr();
	//int t; cin >> t; rep(i, t)
		solve();
	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 66288
final_rank: 10

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 100005

struct Edge{
	Edge(int arg_to,ll arg_weight){
		to = arg_to;
		weight = arg_weight;
	}
	int to;
	ll weight;
};

struct Info{
	Info(int arg_node_id,int arg_pre){
		node_id = arg_node_id;
		pre = arg_pre;
	}
	int node_id,pre;
};

int N;
int root = 0;
int leaf[SIZE];
int num_visit;
int LEFT[SIZE],RIGHT[SIZE];
ll PARENT[SIZE],num_OUT[SIZE],W[SIZE],euler_W[SIZE],edge_W[SIZE];
ll nodes[2*SIZE+5],max_L[2*SIZE+5],max_R[2*SIZE+5];
vector<Edge> G[SIZE];

//オイラーツアーで、ノードのカバー範囲を計算する
void euler_tour(int node_id,int pre_node,ll sum){
	euler_W[node_id] = sum;
	nodes[num_visit] = node_id;
	LEFT[node_id] = num_visit++;

	for(int i = 0; i < G[node_id].size(); i++){
		if(G[node_id][i].to == pre_node)continue;
		edge_W[G[node_id][i].to] = G[node_id][i].weight; //入次の重み
		euler_tour(G[node_id][i].to,node_id,sum+G[node_id][i].weight);
	}
	nodes[num_visit] = node_id;
	RIGHT[node_id] = num_visit++;
}

int main(){

	scanf("%d",&N);

	int from;
	ll weight;

	for(int to = 1; to <= N-1; to++){
		scanf("%d %lld",&from,&weight);
		G[from].push_back(Edge(to,weight));
		G[to].push_back(Edge(from,weight));
	}

	for(int i = 0; i < N; i++){

		num_OUT[i] = 0;
	}

	queue<Info> Q;
	Q.push(Info(root,-1));

	while(!Q.empty()){

		PARENT[Q.front().node_id] = Q.front().pre;

		for(int i = 0; i < G[Q.front().node_id].size(); i++){
			int next = G[Q.front().node_id][i].to;
			if(next == Q.front().pre)continue;

			num_OUT[Q.front().node_id]++;

			Q.push(Info(next,Q.front().node_id));
		}
		Q.pop();
	}

	ll maximum = 0;
	int A,B;

	queue<int> NODE;

	for(int i = 0; i < N; i++){
		if(num_OUT[i] == 0){
			leaf[i] = i;
			W[i] = 0;
			NODE.push(i);
		}
	}

	ll max_path1,max_path2;
	int a,b;

	while(!NODE.empty()){

		int node = NODE.front();
		NODE.pop();

		max_path1 = 0;
		max_path2 = 0;

		b = node;

		for(int i = 0; i < G[node].size(); i++){

			int child = G[node][i].to;
			if(child == PARENT[node])continue;

			ll tmp = W[child]+G[node][i].weight;

			if(tmp > max_path1){

				max_path2 = max_path1;
				b = a;
				max_path1 = tmp;
				W[node] = tmp;
				leaf[node] = leaf[child];
				a = leaf[child];

			}else if(tmp > max_path2){

				max_path2 = tmp;
				b = leaf[child];
			}
		}

		if(max_path1+max_path2 > maximum){

			maximum = max_path1+max_path2;
			A = a;
			B = b;
		}
		if(PARENT[node] != -1){
			num_OUT[PARENT[node]]--;
		}
		if(num_OUT[PARENT[node]] == 0){

			NODE.push(PARENT[node]);
		}
	}
	num_visit = 0;
	euler_tour(A,-1,0);

	//基準点より左の最大重み
	max_L[0] = euler_W[A];
	for(int i = 1; i < 2*N; i++){

		max_L[i] = max(max_L[i-1],euler_W[nodes[i]]);
	}
	max_R[2*N-1] = euler_W[A];
	for(int i = 2*N-2; i >= 0; i--){

		max_R[i] = max(max_R[i+1],euler_W[nodes[i]]);
	}

	ll ans = 0;
	ll w_L,w_R;

	for(int i = 0; i < N; i++){
		if(i == A)continue;

		if(LEFT[i] > 0){

			w_L = max_L[LEFT[i]-1];
		}
		if(RIGHT[i]+1 < 2*N){

			w_R = max_R[RIGHT[i]+1];
		}
		ans = max(ans,edge_W[i]+max(w_L,w_R));
	}

	num_visit = 0;
	edge_W[B] = 0;
	euler_tour(B,-1,0);

	//基準点より左の最大重み
	max_L[0] = euler_W[B];
	for(int i = 1; i < 2*N; i++){

		max_L[i] = max(max_L[i-1],euler_W[nodes[i]]);
	}
	max_R[2*N-1] = euler_W[B];
	for(int i = 2*N-2; i >= 0; i--){

		max_R[i] = max(max_R[i+1],euler_W[nodes[i]]);
	}

	for(int i = 0; i < N; i++){
		if(i == B)continue;

		if(LEFT[i] > 0){

			w_L = max_L[LEFT[i]-1];
		}
		if(RIGHT[i]+1 < 2*N){

			w_R = max_R[RIGHT[i]+1];
		}
		ans = max(ans,edge_W[i]+max(w_L,w_R));
	}

	printf("%lld\n",ans);

	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 26852
final_rank: 4

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 100005

struct Edge{
	Edge(int arg_to,ll arg_weight){
		to = arg_to;
		weight = arg_weight;
	}
	int to;
	ll weight;
};

struct Info{
	Info(int arg_node_id,int arg_pre){
		node_id = arg_node_id;
		pre = arg_pre;
	}
	int node_id,pre;
};

int N;
int root = 0;
int leaf[SIZE];
int num_visit;
int LEFT[SIZE],RIGHT[SIZE];
ll PARENT[SIZE],num_OUT[SIZE],W[SIZE],euler_W[SIZE],edge_W[SIZE];
ll nodes[2*SIZE+5],max_L[2*SIZE+5],max_R[2*SIZE+5];
vector<Edge> G[SIZE];

//オイラーツアーで、ノードのカバー範囲を計算する
void euler_tour(int node_id,int pre_node,ll sum){
	euler_W[node_id] = sum;
	nodes[num_visit] = node_id;
	LEFT[node_id] = num_visit++;

	for(int i = 0; i < G[node_id].size(); i++){
		if(G[node_id][i].to == pre_node)continue;
		edge_W[G[node_id][i].to] = G[node_id][i].weight; //入次の重み
		euler_tour(G[node_id][i].to,node_id,sum+G[node_id][i].weight);
	}
	nodes[num_visit] = node_id;
	RIGHT[node_id] = num_visit++;
}

int main(){

	scanf("%d",&N);

	int from;
	ll weight;

	for(int to = 1; to <= N-1; to++){
		scanf("%d %lld",&from,&weight);
		G[from].push_back(Edge(to,weight));
		G[to].push_back(Edge(from,weight));
	}

	for(int i = 0; i < N; i++){

		num_OUT[i] = 0;
	}

	queue<Info> Q;
	Q.push(Info(root,-1));

	while(!Q.empty()){

		PARENT[Q.front().node_id] = Q.front().pre;

		for(int i = 0; i < G[Q.front().node_id].size(); i++){
			int next = G[Q.front().node_id][i].to;
			if(next == Q.front().pre)continue;

			num_OUT[Q.front().node_id]++;

			Q.push(Info(next,Q.front().node_id));
		}
		Q.pop();
	}

	ll maximum = 0;
	int A,B;

	queue<int> NODE;

	for(int i = 0; i < N; i++){
		if(num_OUT[i] == 0){
			leaf[i] = i;
			W[i] = 0;
			NODE.push(i);
		}
	}

	ll max_path1,max_path2;
	int a,b;

	while(!NODE.empty()){

		int node = NODE.front();
		NODE.pop();

		max_path1 = 0;
		max_path2 = 0;

		b = node;

		for(int i = 0; i < G[node].size(); i++){

			int child = G[node][i].to;
			if(child == PARENT[node])continue;

			ll tmp = W[child]+G[node][i].weight;

			if(tmp > max_path1){

				max_path2 = max_path1;
				b = a;
				max_path1 = tmp;
				W[node] = tmp;
				leaf[node] = leaf[child];
				a = leaf[child];

			}else if(tmp > max_path2){

				max_path2 = tmp;
				b = leaf[child];
			}
		}

		/*if(node == root){
			printf("max_path1:%lld path2:%lld\n",max_path1,max_path2);
			printf("a:%d b:%d\n",a,b);
		}*/

		if(max_path1+max_path2 > maximum){

			maximum = max_path1+max_path2;
			A = a;
			B = b;
		}
		if(PARENT[node] != -1){
			num_OUT[PARENT[node]]--;
		}
		if(num_OUT[PARENT[node]] == 0){

			NODE.push(PARENT[node]);
		}
	}

	/*printf("maximum:%lld\n",maximum);
	printf("A:%d B:%d\n",A,B);
*/
	num_visit = 0;
	euler_tour(A,-1,0);

	//基準点より左の最大重み
	max_L[0] = euler_W[A];
	for(int i = 1; i < 2*N; i++){

		max_L[i] = max(max_L[i-1],euler_W[nodes[i]]);
	}
	max_R[2*N-1] = euler_W[A];
	for(int i = 2*N-2; i >= 0; i--){

		max_R[i] = max(max_R[i+1],euler_W[nodes[i]]);
	}

	ll ans = 0;
	ll w_L,w_R;

	for(int i = 0; i < N; i++){
		if(i == A)continue;

		if(LEFT[i] > 0){

			w_L = max_L[LEFT[i]-1];
		}
		if(RIGHT[i]+1 < 2*N){

			w_R = max_R[RIGHT[i]+1];
		}
		ans = max(ans,edge_W[i]+max(w_L,w_R));
	}

	num_visit = 0;
	edge_W[B] = 0;
	euler_tour(B,-1,0);

	//基準点より左の最大重み
	max_L[0] = euler_W[B];
	for(int i = 1; i < 2*N; i++){

		max_L[i] = max(max_L[i-1],euler_W[nodes[i]]);
	}
	max_R[2*N-1] = euler_W[B];
	for(int i = 2*N-2; i >= 0; i--){

		max_R[i] = max(max_R[i+1],euler_W[nodes[i]]);
	}

	for(int i = 0; i < N; i++){
		if(i == B)continue;

		if(LEFT[i] > 0){

			w_L = max_L[LEFT[i]-1];
		}
		if(RIGHT[i]+1 < 2*N){

			w_R = max_R[RIGHT[i]+1];
		}
		ans = max(ans,edge_W[i]+max(w_L,w_R));
	}

	printf("%lld\n",ans);

	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 26856
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;


vector<P> G[100001];
vector<P> dp1(100000);
P dfs1(int u,int t){
    P ret;
    ret.first=0;
    ret.second=0;
    for(auto v:G[u]){
        if(v.first==t) continue;
        P p = dfs1(v.first,u);
        ret.first=max(ret.first,p.first+v.second);
        ret.second=max({ret.second,p.second,v.second});
    }
    return dp1[u]=ret;
}

int dfs2(int u,int t,int d,int e){
    vector<pair<P,int>> A;
    vector<P> dd,ee;
    A.push_back({{0,0},-1});
    A.push_back({{0,0},-1});
    for(auto v:G[u]){
        if(v.first==t){
            A.push_back({{d+v.second,e},v.first});
        }
        else{
            A.push_back({{dp1[v.first].first+v.second,max(dp1[v.first].second,v.second)},v.first});
        }
    }
    sort(A.rbegin(),A.rend());
    int ret=0;
    for(auto v:A){
        int sum = v.first.second;
        if(v.second==A[0].second){
            sum += A[1].first.first;
            sum += A[2].first.first;
        }
        else if(v.second==A[1].second){
            sum += A[0].first.first;
            sum += A[2].first.first;
        }
        else{
            sum += A[0].first.first;
            sum += A[1].first.first;
        }
        ret = max(ret,sum);

        dd.push_back({v.first.first,v.second});
        ee.push_back({v.first.second,v.second});
    }
    sort(dd.rbegin(),dd.rend());
    sort(ee.rbegin(),ee.rend());
    for(auto v:G[u]){
        if(v.first==t) continue;
        int nd=dd[0].first,ne=ee[0].first;
        if(dd[0].second==v.first) nd=dd[1].first;
        if(ee[0].second==v.first) ne=ee[1].first;
        ret=max(ret,dfs2(v.first,u,nd,max(ne,v.second)));
    }
    return ret;
}

int main(){
    int n;cin >> n;
    for (int i = 0; i < n-1; i++) {
        int p,w;cin >> p >> w;
        G[i+1].push_back({p,w});
        G[p].push_back({i+1,w});
    }
    dfs1(0,-1);
    cout << dfs2(0,-1,0,0) << endl;
}
accuracy: 1
time_ms: 110
memory_kb: 46648
final_rank: 11

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int N;
vector<pair<int,int> >G[1<<17];
pair<int,int>dp1[1<<17];
pair<int,int>dfs1(int u,int p)
{
	pair<int,int>ret;
	ret.first=ret.second=0;
	for(pair<int,int>q:G[u])
	{
		if(q.first==p)continue;
		pair<int,int>now=dfs1(q.first,u);
		ret.first=max(ret.first,now.first+q.second);
		ret.second=max(ret.second,max(now.second,q.second));
	}
	dp1[u]=ret;
	return ret;
}
int ans;
void dfs2(int u,int p,pair<int,int>P)
{
	vector<pair<pair<int,int>,int> >A;
	A.push_back(make_pair(P,-1));
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].first;
		if(v==p)continue;
		A.push_back(make_pair(make_pair(dp1[v].first+G[u][i].second,max(dp1[v].second,G[u][i].second)),i));
	}
	sort(A.rbegin(),A.rend());
	pair<int,int>dmax1,dmax2,emax1,emax2;
	dmax1=dmax2=emax1=emax2=make_pair(0,-1);
	while(A.size()<3)A.push_back(make_pair(make_pair(0,0),-(int)A.size()-1));
	for(int i=0;i<A.size();i++)
	{
		ans=max(ans,A[i].first.second+A[i==0?2:0].first.first+A[i==1?2:1].first.first);
		if(dmax1.first<=A[i].first.first)
		{
			dmax2=dmax1;
			dmax1=make_pair(A[i].first.first,A[i].second);
		}
		else if(dmax2.first<=A[i].first.first)
		{
			dmax2=make_pair(A[i].first.first,A[i].second);
		}
		if(emax1.first<=A[i].first.second)
		{
			emax2=emax1;
			emax1=make_pair(A[i].first.second,A[i].second);
		}
		else if(emax2.first<=A[i].first.second)
		{
			emax2=make_pair(A[i].first.second,A[i].second);
		}
	}
	for(int i=0;i<G[u].size();i++)
	{
		if(G[u][i].first==p)continue;
		dfs2(G[u][i].first,u,make_pair(G[u][i].second+(dmax1.second==i?dmax2.first:dmax1.first),max(G[u][i].second,emax1.second==i?emax2.first:emax1.first)));
	}
}
main()
{
	cin>>N;
	for(int i=1;i<N;i++)
	{
		int p,w;cin>>p>>w;
		G[p].push_back(make_pair(i,w));
		G[i].push_back(make_pair(p,w));
	}
	dfs1(0,-1);
	dfs2(0,-1,make_pair(0,0));
	cout<<ans<<endl;
}
accuracy: 1
time_ms: 80
memory_kb: 33472
final_rank: 6

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int N;
vector<pair<int,int> >G[1<<17];
pair<int,int>dp1[1<<17];
pair<int,int>dfs1(int u,int p)
{
	pair<int,int>ret;
	ret.first=ret.second=0;
	for(pair<int,int>q:G[u])
	{
		if(q.first==p)continue;
		pair<int,int>now=dfs1(q.first,u);
		ret.first=max(ret.first,now.first+q.second);
		ret.second=max(ret.second,max(now.second,q.second));
	}
	dp1[u]=ret;
	return ret;
}
int ans;
void dfs2(int u,int p,pair<int,int>P)
{
	vector<pair<pair<int,int>,int> >A;
	A.push_back(make_pair(P,-1));
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].first;
		if(v==p)continue;
		A.push_back(make_pair(make_pair(dp1[v].first+G[u][i].second,max(dp1[v].second,G[u][i].second)),i));
	}
	sort(A.rbegin(),A.rend());
	pair<int,int>dmax1,dmax2,emax1,emax2;
	dmax1=dmax2=emax1=emax2=make_pair(0,-1);
	while(A.size()<3)A.push_back(make_pair(make_pair(0,0),-(int)A.size()-1));
	for(int i=0;i<A.size();i++)
	{
		ans=max(ans,A[i].first.second+A[i==0?2:0].first.first+A[i==1?2:1].first.first);
		if(dmax1.first<=A[i].first.first)
		{
			dmax2=dmax1;
			dmax1=make_pair(A[i].first.first,A[i].second);
		}
		else if(dmax2.first<=A[i].first.first)
		{
			dmax2=make_pair(A[i].first.first,A[i].second);
		}
		if(emax1.first<=A[i].first.second)
		{
			emax2=emax1;
			emax1=make_pair(A[i].first.second,A[i].second);
		}
		else if(emax2.first<=A[i].first.second)
		{
			emax2=make_pair(A[i].first.second,A[i].second);
		}
	}
	for(int i=0;i<G[u].size();i++)
	{
		if(G[u][i].first==p)continue;
		dfs2(G[u][i].first,u,make_pair(G[u][i].second+(dmax1.second==i?dmax2.first:dmax1.first),max(G[u][i].second,emax1.second==i?emax2.first:emax1.first)));
	}
}
main()
{
	cin>>N;
	for(int i=1;i<N;i++)
	{
		int p,w;cin>>p>>w;
		G[p].push_back(make_pair(i,w));
		G[i].push_back(make_pair(p,w));
	}
	dfs1(0,-1);
	dfs2(0,-1,make_pair(0,0));
	cout<<ans<<endl;
}
accuracy: 1
time_ms: 90
memory_kb: 33476
final_rank: 7

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
#include <utility>
#include <cassert>
using namespace std;
using ll = long long;

pair<ll,ll> dfs(const vector<vector<pair<ll,int>>> &G, vector<pair<ll,ll>> &D, const int v, const int prev){
  ll t = 0, s = 0;
  for(auto e : G[v]){
    int v_ = e.second;
    ll w = e.first;
    if(v_ == prev) continue;
    pair<ll,ll> p = dfs(G,D,v_,v);
    ll x = max(p.first,p.second);
    s = max(s,x+w);
    if(s > t) swap(s,t);
  }
  D[v] = {t,s};
  return D[v];
}

pair<ll,ll> top2(pair<ll,ll> A, pair<ll,ll> B){
  assert(A.first >= A.second);
  assert(B.first >= B.second);
  if(A < B) swap(A,B);
  pair<ll,ll> ret = A;
  ret.second = max(ret.second,B.first);
  return ret;
}

ll solve(const vector<vector<pair<long long,int>>> &G, int v, int prev,
         const vector<pair<ll,ll>> &D, const pair<ll,ll> ts){
  int N = G[v].size();
  vector<pair<ll,ll>> E(N+1,{0,0}), B(N+1,{0,0});
  for(int i = 0; i < N; ++i){
    pair<ll,int> e = G[v][i];
    int v_ = e.second;
    ll w = e.first, l = 0;
    if(v_ == prev) l = max(ts.first,ts.second);
    else l = max(D[v_].first,D[v_].second);
    E[i+1].first = l+w;
    B[i  ].first = l+w;
  }
  for(int i = 1; i <= N; ++i) E[i] = top2(E[i],E[i-1]);
  for(int i = N-1; i >= 0; --i) B[i] = top2(B[i],B[i+1]);
  ll ret = 0;
  for(int i = 0; i < N; ++i){
    ll w = G[v][i].first;
    int v_ = G[v][i].second;
    pair<ll,ll> p = D[v_];
    if(v_ == prev) p = ts;
    ret = max(ret,w+p.first+p.second);
    p = top2(E[i],B[i+1]);
    ret = max(ret,w+p.first+p.second);
  }
  for(int i = 0; i < N; ++i){
    int v_ = G[v][i].second;
    if(v_ == prev) continue;
    pair<ll,ll> ts_ = top2(E[i],B[i+1]);
    ret = max(ret,solve(G,v_,v,D,ts_));
  }
  return ret;
}

int main(){
  int N;
  cin >> N;
  vector<vector<pair<long long,int>>> G(N);
  for(int i = 0; i < N-1; ++i){
    int p;
    long long w;
    cin >> p >> w;
    G[p].emplace_back(w,i+1);
    G[i+1].emplace_back(w,p);
  }
  vector<pair<ll,ll>> D(N,{0,0});
  pair<ll,ll> p = dfs(G,D,0,-1);
  ll ans = p.first+p.second;
  pair<ll,ll> ts(0,0);
  cout << max(ans,solve(G,0,-1,D,ts)) << endl;
}
accuracy: 0.3728813559322034
time_ms: 90
memory_kb: 38456
final_rank: 17

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
#include <utility>
#include <cassert>
using namespace std;
using ll = long long;

pair<ll,ll> dfs(const vector<vector<pair<ll,int>>> &G, vector<pair<ll,ll>> &D, const int v, const int prev){
  ll t = 0, s = 0;
  for(auto e : G[v]){
    int v_ = e.second;
    ll w = e.first;
    if(v_ == prev) continue;
    pair<ll,ll> p = dfs(G,D,v_,v);
    ll x = max(p.first,p.second);
    s = max(s,x+w);
    if(s > t) swap(s,t);
  }
  D[v] = {t,s};
  return D[v];
}

pair<ll,ll> top2(pair<ll,ll> A, pair<ll,ll> B){
  assert(A.first >= A.second);
  assert(B.first >= B.second);
  if(A < B) swap(A,B);
  pair<ll,ll> ret = A;
  ret.second = max(ret.second,B.first);
  return ret;
}

ll solve(const vector<vector<pair<long long,int>>> &G, int v, int prev,
         const vector<pair<ll,ll>> &D, const pair<ll,ll> ts){
  int N = G[v].size();
  vector<pair<ll,ll>> E(N+1,{0,0}), B(N+1,{0,0});
  for(int i = 0; i < N; ++i){
    pair<ll,int> e = G[v][i];
    int v_ = e.second;
    ll w = e.first, l = 0;
    if(v_ == prev) l = max(ts.first,ts.second);
    else l = max(D[v_].first,D[v_].second);
    E[i+1].first = l+w;
    B[i  ].first = l+w;
  }
  for(int i = 1; i <= N; ++i) E[i] = top2(E[i],E[i-1]);
  for(int i = N-1; i >= 0; --i) B[i] = top2(B[i],B[i+1]);
  ll ret = 0;
  for(int i = 0; i < N; ++i){
    ll w = G[v][i].first;
    int v_ = G[v][i].second;
    pair<ll,ll> p = D[v_];
    if(v_ == prev) p = ts;
    ret = max(ret,w+p.first+p.second);
    p = top2(E[i],B[i+1]);
    ret = max(ret,w+p.first+p.second);
  }
  for(int i = 0; i < N; ++i){
    int v_ = G[v][i].second;
    if(v_ == prev) continue;
    pair<ll,ll> ts_ = top2(E[i],B[i+1]);
    ret = max(ret,solve(G,v_,v,D,ts_));
  }
  return ret;
}

int main(){
  int N;
  cin >> N;
  vector<vector<pair<long long,int>>> G(N);
  for(int i = 0; i < N-1; ++i){
    int p;
    long long w;
    cin >> p >> w;
    G[p].emplace_back(w,i+1);
    G[i+1].emplace_back(w,p);
  }
  vector<pair<ll,ll>> D(N,{0,0});
  dfs(G,D,0,-1);
  pair<ll,ll> ts(0,0);
  cout << solve(G,0,-1,D,ts)  << endl;
}
accuracy: 0.3728813559322034
time_ms: 90
memory_kb: 38336
final_rank: 14

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
#include <utility>
#include <cassert>
using namespace std;
using ll = long long;

pair<ll,ll> dfs(const vector<vector<pair<ll,int>>> &G, vector<pair<ll,ll>> &D, int v, int prev){
  ll t = 0, s = 0;
  for(auto e : G[v]){
    int v_ = e.second;
    ll w = e.first;
    if(v_ == prev) continue;
    pair<ll,ll> p = dfs(G,D,v_,v);
    ll x = max(p.first,p.second);
    s = max(s,x+w);
    if(s > t) swap(s,t);
  }
  D[v] = {t,s};
  return D[v];
}

pair<ll,ll> top2(pair<ll,ll> A, pair<ll,ll> B){
  assert(A.first >= A.second);
  assert(B.first >= B.second);
  if(A < B) swap(A,B);
  pair<ll,ll> ret = A;
  ret.second = max(ret.second,B.first);
  return ret;
}

ll solve(const vector<vector<pair<long long,int>>> &G, int v, int prev, vector<pair<ll,ll>> &D, pair<ll,ll> ts){
  int N = G[v].size();
  vector<pair<ll,ll>> E(N+1,{0,0}), B(N+1,{0,0});
  for(int i = 0; i < N; ++i){
    pair<ll,int> e = G[v][i];
    int v_ = e.second;
    ll w = e.first, l = 0;
    if(v_ == prev) l = max(ts.first,ts.second);
    else l = max(D[v_].first,D[v_].second);
    E[i+1].first = l+w;
    B[i  ].first = l+w;
  }
  for(int i = 1; i <= N; ++i) E[i] = top2(E[i],E[i-1]);
  for(int i = N-1; i >= 0; --i) B[i] = top2(B[i],B[i+1]);
  ll ret = 0;
  for(int i = 0; i < N; ++i){
    ll w = G[v][i].first;
    int v_ = G[v][i].second;
    pair<ll,ll> p = D[v_];
    if(v_ == prev) p = ts;
    ret = max(ret,w+p.first+p.second);
    p = top2(E[i],B[i+1]);
    ret = max(ret,w+p.first+p.second);
  }
  for(int i = 0; i < N; ++i){
    int v_ = G[v][i].second;
    if(v_ == prev) continue;
    pair<ll,ll> ts_ = top2(E[i],B[i+1]);
    ret = max(ret,solve(G,v_,v,D,ts_));
  }
  return ret;
}

int main(){
  int N;
  cin >> N;
  vector<vector<pair<long long,int>>> G(N);
  long long ans = 0;
  for(int i = 0; i < N-1; ++i){
    int p;
    long long w;
    cin >> p >> w;
    G[p].emplace_back(w,i+1);
    G[i+1].emplace_back(w,p);
    ans = max(ans,w);
  }
  vector<pair<ll,ll>> D(N,{0,0});
  dfs(G,D,0,-1);
  // for(int i = 0; i < N; ++i)
  //   cerr << D[i].first << " " << D[i].second << endl;
  pair<ll,ll> ts(0,0);
  ans = max(ans,solve(G,0,-1,D,ts));
  cout << ans << endl;
}
accuracy: 0.3728813559322034
time_ms: 90
memory_kb: 38336
final_rank: 14

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
#include <utility>
#include <cassert>
using namespace std;
const long long INF = 1e9;
using ll = long long;

pair<ll,ll> dfs(const vector<vector<pair<ll,int>>> &G, vector<pair<ll,ll>> &D, int v, int prev){
  ll t = 0, s = 0;
  for(auto e : G[v]){
    int v_ = e.second;
    ll w = e.first;
    if(v_ == prev) continue;
    pair<ll,ll> p = dfs(G,D,v_,v);
    ll x = max(p.first,p.second);
    s = max(s,x+w);
    if(s > t) swap(s,t);
  }
  D[v] = {t,s};
  return D[v];
}

pair<ll,ll> top2(pair<ll,ll> A, pair<ll,ll> B){
  assert(A.first >= A.second);
  assert(B.first >= B.second);
  if(A < B) swap(A,B);
  pair<ll,ll> ret = A;
  ret.second = max(ret.second,B.first);
  return ret;
}

ll solve(const vector<vector<pair<long long,int>>> &G, int v, int prev, vector<pair<ll,ll>> &D, pair<ll,ll> ts){
  int N = G[v].size();
  vector<pair<ll,ll>> E(N+1,{0,0}), B(N+1,{0,0});
  for(int i = 0; i < N; ++i){
    pair<ll,int> e = G[v][i];
    int v_ = e.second;
    ll w = e.first, l = 0;
    if(v_ == prev) l = max(ts.first,ts.second);
    else l = max(D[v_].first,D[v_].second);
    E[i+1].first = l+w;
    B[i  ].first = l+w;
  }
  for(int i = 1; i <= N; ++i) E[i] = top2(E[i],E[i-1]);
  for(int i = N-1; i >= 0; --i) B[i] = top2(B[i],B[i+1]);
  ll ret = 0;
  for(int i = 0; i < N; ++i){
    ll w = G[v][i].first;
    int v_ = G[v][i].second;
    pair<ll,ll> p = D[v_];
    if(v_ == prev) p = ts;
    ret = max(ret,w+p.first+p.second);
    p = top2(E[i],B[i+1]);
    ret = max(ret,w+p.first+p.second);
  }
  for(int i = 0; i < N; ++i){
    int v_ = G[v][i].second;
    if(v_ == prev) continue;
    pair<ll,ll> ts_ = top2(E[i],B[i+1]);
    ret = max(ret,solve(G,v_,v,D,ts_));
  }
  return ret;
}

int main(){
  int N;
  cin >> N;
  vector<vector<pair<long long,int>>> G(N);
  long long ans = -INF;
  for(int i = 0; i < N-1; ++i){
    int p;
    long long w;
    cin >> p >> w;
    G[p].emplace_back(w,i+1);
    G[i+1].emplace_back(w,p);
    ans = max(ans,w);
  }
  vector<pair<ll,ll>> D(N,{0,0});
  dfs(G,D,0,-1);
  // for(int i = 0; i < N; ++i)
  //   cerr << D[i].first << " " << D[i].second << endl;
  pair<ll,ll> ts(0,-INF);
  ans = max(ans,solve(G,0,-1,D,ts));
  cout << ans << endl;
}
accuracy: 0.3728813559322034
time_ms: 90
memory_kb: 38296
final_rank: 12

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
#include <utility>
#include <cassert>
using namespace std;
const long long INF = 1e9;
using ll = long long;

pair<ll,ll> dfs(const vector<vector<pair<ll,int>>> &G, vector<pair<ll,ll>> &D, int v, int prev){
  ll t = 0, s = -INF;
  for(auto e : G[v]){
    int v_ = e.second;
    ll w = e.first;
    if(v_ == prev) continue;
    pair<ll,ll> p = dfs(G,D,v_,v);
    ll x = max(p.first,p.second);
    s = max(s,x+w);
    if(s > t) swap(s,t);
  }
  D[v] = {t,s};
  return D[v];
}

pair<ll,ll> top2(pair<ll,ll> A, pair<ll,ll> B){
  assert(A.first >= A.second);
  assert(B.first >= B.second);
  if(A < B) swap(A,B);
  pair<ll,ll> ret = A;
  ret.second = max(ret.second,B.first);
  return ret;
}

ll solve(const vector<vector<pair<long long,int>>> &G, int v, int prev, vector<pair<ll,ll>> &D, pair<ll,ll> ts){
  int N = G[v].size();
  vector<pair<ll,ll>> E(N+1,{0,0}), B(N+1,{0,0});
  for(int i = 0; i < N; ++i){
    pair<ll,int> e = G[v][i];
    int v_ = e.second;
    ll w = e.first, l = -INF;
    if(v_ == prev) l = max(ts.first,ts.second);
    else l = max(D[v_].first,D[v_].second);
    E[i+1].first = l+w;
    B[i  ].first = l+w;
  }
  for(int i = 1; i <= N; ++i) E[i] = top2(E[i],E[i-1]);
  for(int i = N-1; i >= 0; --i) B[i] = top2(B[i],B[i+1]);
  ll ret = -INF;
  for(int i = 0; i < N; ++i){
    ll w = G[v][i].first;
    int v_ = G[v][i].second;
    pair<ll,ll> p = D[v_];
    if(v_ == prev) p = ts;
    ret = max(ret,w+p.first+p.second);
    p = top2(E[i],B[i+1]);
    ret = max(ret,w+p.first+p.second);
  }
  for(int i = 0; i < N; ++i){
    int v_ = G[v][i].second;
    if(v_ == prev) continue;
    pair<ll,ll> ts_ = top2(E[i],B[i+1]);
    ret = max(ret,solve(G,v_,v,D,ts_));
  }
  return ret;
}

int main(){
  int N;
  cin >> N;
  vector<vector<pair<long long,int>>> G(N);
  long long ans = -INF;
  for(int i = 0; i < N-1; ++i){
    int p;
    long long w;
    cin >> p >> w;
    G[p].emplace_back(w,i+1);
    G[i+1].emplace_back(w,p);
    ans = max(ans,w);
  }
  vector<pair<ll,ll>> D(N,{0,0});
  dfs(G,D,0,-1);
  // for(int i = 0; i < N; ++i)
  //   cerr << D[i].first << " " << D[i].second << endl;
  pair<ll,ll> ts(0,-INF);
  ans = max(ans,solve(G,0,-1,D,ts));
  cout << ans << endl;
}
accuracy: 0.3728813559322034
time_ms: 90
memory_kb: 38324
final_rank: 13

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
#include <utility>
#include <cassert>
using namespace std;
const long long INF = 1e9;
using ll = long long;

pair<ll,ll> dfs(const vector<vector<pair<ll,int>>> &G, vector<pair<ll,ll>> &D, int v, int prev){
  ll t = 0, s = -INF;
  for(auto e : G[v]){
    int v_ = e.second;
    ll w = e.first;
    if(v_ == prev) continue;
    pair<ll,ll> p = dfs(G,D,v_,v);
    ll x = max(p.first,p.second);
    s = max(s,x+w);
    if(s > t) swap(s,t);
  }
  D[v] = {t,s};
  return D[v];
}

pair<ll,ll> top2(pair<ll,ll> A, pair<ll,ll> B){
  assert(A.first >= A.second);
  assert(B.first >= B.second);
  if(A < B) swap(A,B);
  pair<ll,ll> ret = A;
  ret.second = max(ret.second,B.first);
  return ret;
}

ll solve(const vector<vector<pair<long long,int>>> &G, int v, int prev, vector<pair<ll,ll>> &D, pair<ll,ll> ts){
  int N = G[v].size();
  vector<pair<ll,ll>> E(N+1,{-INF,-INF}), B(N+1,{-INF,-INF});
  for(int i = 0; i < N; ++i){
    pair<ll,int> e = G[v][i];
    int v_ = e.second;
    ll w = e.first, l = -INF;
    if(v_ == prev) l = max(ts.first,ts.second);
    else l = max(D[v_].first,D[v_].second);
    E[i+1].first = l+w;
    B[i  ].first = l+w;
  }
  for(int i = 1; i <= N; ++i) E[i] = top2(E[i],E[i-1]);
  for(int i = N-1; i >= 0; --i) B[i] = top2(B[i],B[i+1]);
  ll ret = -INF;
  for(int i = 0; i < N; ++i){
    ll w = G[v][i].first;
    int v_ = G[v][i].second;
    pair<ll,ll> p = D[v_];
    if(v_ == prev) p = ts;
    ret = max(ret,w+p.first+p.second);
    p = top2(E[i],B[i+1]);
    ret = max(ret,w+p.first+p.second);
    ret = max(ret,w+p.first);
  }
  for(int i = 0; i < N; ++i){
    int v_ = G[v][i].second;
    if(v_ == prev) continue;
    pair<ll,ll> ts_ = top2(E[i],B[i+1]);
    ret = max(ret,solve(G,v_,v,D,ts_));
  }
  return ret;
}

int main(){
  int N;
  cin >> N;
  vector<vector<pair<long long,int>>> G(N);
  long long ans = -INF;
  for(int i = 0; i < N-1; ++i){
    int p;
    long long w;
    cin >> p >> w;
    G[p].emplace_back(w,i+1);
    G[i+1].emplace_back(w,p);
    ans = max(ans,w);
  }
  vector<pair<ll,ll>> D(N,{0,-INF});
  dfs(G,D,0,-1);
  // for(int i = 0; i < N; ++i)
  //   cerr << D[i].first << " " << D[i].second << endl;
  pair<ll,ll> ts(0,-INF);
  ans = max(ans,solve(G,0,-1,D,ts));
  cout << ans << endl;
}
accuracy: 0.3728813559322034
time_ms: 90
memory_kb: 38452
final_rank: 16

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
#include <utility>
#include <cassert>
using namespace std;
const long long INF = 1e9;
using ll = long long;

pair<ll,ll> dfs(const vector<vector<pair<ll,int>>> &G, vector<pair<ll,ll>> &D, int v, int prev){
  ll t = 0, s = -INF;
  for(auto e : G[v]){
    int v_ = e.second;
    ll w = e.first;
    if(v_ == prev) continue;
    pair<ll,ll> p = dfs(G,D,v_,v);
    ll x = max(p.first,p.second);
    s = max(s,x+w);
    if(s > t) swap(s,t);
  }
  D[v] = {t,s};
  return D[v];
}

pair<ll,ll> top2(pair<ll,ll> A, pair<ll,ll> B){
  assert(A.first >= A.second);
  assert(B.first >= B.second);
  if(A < B) swap(A,B);
  pair<ll,ll> ret = A;
  ret.second = max(ret.second,B.first);
  return ret;
}

ll solve(const vector<vector<pair<long long,int>>> &G, int v, int prev, vector<pair<ll,ll>> &D, pair<ll,ll> ts){
  int N = G[v].size();
  vector<pair<ll,ll>> E(N+1,{-INF,-INF}), B(N+1,{-INF,-INF});
  for(int i = 0; i < N; ++i){
    pair<ll,int> e = G[v][i];
    int v_ = e.second;
    ll w = e.first, l = -INF;
    if(v_ == prev) l = max(ts.first,ts.second);
    else l = max(D[v_].first,D[v_].second);
    E[i+1].first = l+w;
    B[i  ].first = l+w;
  }
  for(int i = 1; i <= N; ++i) E[i] = top2(E[i],E[i-1]);
  for(int i = N-1; i >= 0; --i) B[i] = top2(B[i],B[i+1]);
  ll ret = -INF;
  for(int i = 0; i < N; ++i){
    ll w = G[v][i].first;
    int v_ = G[v][i].second;
    pair<ll,ll> p = D[v_];
    if(v_ == prev) p = ts;
    ret = max(ret,w+p.first+p.second);
    p = top2(E[i],B[i+1]);
    ret = max(ret,w+p.first+p.second);
  }
  for(int i = 0; i < N; ++i){
    int v_ = G[v][i].second;
    if(v_ == prev) continue;
    pair<ll,ll> ts_ = top2(E[i],B[i+1]);
    ret = max(ret,solve(G,v_,v,D,ts_));
  }
  return ret;
}

int main(){
  int N;
  cin >> N;
  vector<vector<pair<long long,int>>> G(N);
  long long ans = -INF;
  for(int i = 0; i < N-1; ++i){
    int p;
    long long w;
    cin >> p >> w;
    G[p].emplace_back(w,i+1);
    G[i+1].emplace_back(w,p);
    ans = max(ans,w);
  }
  vector<pair<ll,ll>> D(N,{0,-INF});
  dfs(G,D,0,-1);
  // for(int i = 0; i < N; ++i)
  //   cerr << D[i].first << " " << D[i].second << endl;
  pair<ll,ll> ts(0,-INF);
  ans = max(ans,solve(G,0,-1,D,ts));
  cout << ans << endl;
}
accuracy: 0.3220338983050847
time_ms: 90
memory_kb: 28688
final_rank: 18