#include <bits/stdc++.h>

using namespace std;

struct UnionFind {
  vector< int > data;

  UnionFind(int sz) {
    data.assign(sz, -1);
  }

  bool unite(int x, int y) {
    x = find(x), y = find(y);
    if(x == y) return (false);
    if(data[x] > data[y]) swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return (true);
  }

  int find(int k) {
    if(data[k] < 0) return (k);
    return (data[k] = find(data[k]));
  }

  int size(int k) {
    return (-data[find(k)]);
  }
};


template< typename T, typename F >
T boruvka(int N, F f) {
  vector< int > rev(N), belong(N);
  UnionFind uf(N);
  T ret = T();
  while(uf.size(0) != N) {
    int ptr = 0;
    for(int i = 0; i < N; i++) {
      if(uf.find(i) == i) {
        belong[i] = ptr++;
        rev[belong[i]] = i;
      }
    }
    for(int i = 0; i < N; i++) {
      belong[i] = belong[uf.find(i)];
    }
    auto v = f(ptr, belong);
    bool update = false;
    for(int i = 0; i < ptr; i++) {
      if(~v[i].second && uf.unite(rev[i], rev[v[i].second])) {
        ret += v[i].first;
        update = true;
      }
    }
    if(!update) return -1; // notice!!
  }
  return ret;
}


template< typename T >
struct edge {
  int src, to;
  T cost;

  edge(int to, T cost) : src(-1), to(to), cost(cost) {}

  edge(int src, int to, T cost) : src(src), to(to), cost(cost) {}

  edge &operator=(const int &x) {
    to = x;
    return *this;
  }

  operator int() const { return to; }
};

template< typename T >
using Edges = vector< edge< T > >;
template< typename T >
using WeightedGraph = vector< Edges< T > >;
using UnWeightedGraph = vector< vector< int > >;
template< typename T >
using Matrix = vector< vector< T > >;

using int64 = long long;
const int64 INF = 1LL << 60;

template< typename Data, typename T, typename F1, typename F2 >
struct ReRooting {

  struct Node {
    int to, rev;
    Data data;
  };

  vector< vector< Node > > g;
  vector< vector< T > > ldp, rdp;
  vector< int > lptr, rptr;
  const F1 f1;
  const F2 f2;
  const T ident;

  ReRooting(int n, const F1 &f1, const F2 &f2, const T &ident) :
      g(n), ldp(n), rdp(n), lptr(n), rptr(n), f1(f1), f2(f2), ident(ident) {}

  void add_edge(int u, int v, const Data &d) {
    g[u].emplace_back((Node) {v, (int) g[v].size(), d});
    g[v].emplace_back((Node) {u, (int) g[u].size() - 1, d});
  }

  T dfs(int idx, int par) {

    while(lptr[idx] != par && lptr[idx] < g[idx].size()) {
      auto &e = g[idx][lptr[idx]];
      ldp[idx][lptr[idx] + 1] = f1(ldp[idx][lptr[idx]], f2(dfs(e.to, e.rev), idx, e.to, e.data));
      ++lptr[idx];
    }
    while(rptr[idx] != par && rptr[idx] >= 0) {
      auto &e = g[idx][rptr[idx]];
      rdp[idx][rptr[idx]] = f1(rdp[idx][rptr[idx] + 1], f2(dfs(e.to, e.rev), idx, e.to, e.data));
      --rptr[idx];
    }
    if(par < 0) return rdp[idx][0];
    return f1(ldp[idx][par], rdp[idx][par + 1]);
  }

  vector< T > solve() {
    for(int i = 0; i < g.size(); i++) {
      ldp[i].assign(g[i].size() + 1, ident);
      rdp[i].assign(g[i].size() + 1, ident);
      lptr[i] = 0;
      rptr[i] = (int) g[i].size() - 1;
    }
    vector< T > ret;
    for(int i = 0; i < g.size(); i++) {
      ret.push_back(dfs(i, -1));
    }
    return ret;
  }
};


int main() {
  int N, X[200000];
  cin >> N;
  for(int i = 0; i < N; i++) {
    cin >> X[i];
  }

  using pii = pair< pair< int64, int >, pair< int64, int > >;
  auto f1 = [](pii a, const pii &b) {
    for(auto p : {b.first, b.second}) {
      if(a.first.second == p.second) {
        a.first.first = min(a.first.first, p.first);
      } else if(a.second.second == p.second) {
        a.second.first = min(a.second.first, p.first);
        if(a.first > a.second) swap(a.first, a.second);
      } else {
        if(p < a.first) {
          a.second = a.first;
          a.first = p;
        } else if(p < a.second) {
          a.second = p;
        }
      }
    }
    return a;
  };
  vector< int > belong;
  auto f2 = [&](pii a, int src, int to, int64 cost) {
    a = f1(a, pii(make_pair(X[to], belong[to]), make_pair(INF, -1)));
    a.first.first = min(INF, a.first.first + cost);
    a.second.first = min(INF, a.second.first + cost);
    return a;
  };


  ReRooting< int64, pii, decltype(f1), decltype(f2) > g(N, f1, f2, pii(make_pair(INF, -1), make_pair(INF, -1)));
  for(int i = 1; i < N; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    --a, --b;
    g.add_edge(a, b, c);
  }

  function< vector< pair< int64, int > >(int, vector< int >) > f = [&](int sz, vector< int > be) {
    belong = be;
    vector< pair< int64, int > > ret(sz, {INF, -1});
    auto v = g.solve();
    for(int i = 0; i < v.size(); i++) {
      auto obj = v[i].first;
      if(obj.second == belong[i]) obj = v[i].second;
      obj.first += X[i];
      ret[belong[i]] = min(ret[belong[i]], obj);
    }
    return ret;
  };
  cout << boruvka< int64, decltype(f) >(N, f) << endl;
}







Measured memory_bytes: 156872