#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
using namespace std;

#ifdef LOCAL
	#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
	#define eprintf(...) 42
#endif

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, int> pli;
#define mp make_pair

const ll INF = (ll)1e18;
const int N = 200200;
int n;
vector<pli> g[N];
ll d[N];
ll X[N];
ll ANS = 0;
int par[N];
int sz[N];
pli bestInSubtree[N][2];
int all[N];
int allSz;
int col[N];
pli bestEdge[N];

void dfs0(int v, int p) {
	for (pli e : g[v]) {
		int u = e.second;
		if (u == p) continue;
		d[u] = d[v] + e.first;
		dfs0(u, v);
	}
}

int getPar(int v) {
	return par[v] == -1 ? v : par[v] = getPar(par[v]);
}
bool unite(int v, int u) {
	v = getPar(v);
	u = getPar(u);
	if (v == u) return false;
	if (sz[v] < sz[u]) swap(v, u);
	sz[v] += sz[u];
	par[u] = v;
	return true;
}

void dfs1(int v, int p) {
//	cerr << "dfs1 " << v << endl;
	bestInSubtree[v][0] = mp(d[v] + X[v], col[v]);
	bestInSubtree[v][1] = mp(INF, -1);
	for (pli e : g[v]) {
		int u = e.second;
		if (u == p) continue;
		dfs1(u, v);
		for (int i = 0; i < 2; i++) {
			pli t = bestInSubtree[u][i];
			if (t < bestInSubtree[v][0])
				swap(bestInSubtree[v][0], t);
			if (t < bestInSubtree[v][1] && t.second != bestInSubtree[v][0].second)
				swap(bestInSubtree[v][1], t);
		}
	}
}

void dfs2(int v, int p, pli fb, pli sb) {
//	cerr << "dfs2 " << v << endl;
	for (int i = 0; i < 2; i++) {
		pli t = bestInSubtree[v][i];
		t.first -= 2 * d[v];
		if (t < fb) swap(t, fb);
		if (t < sb && t.second != fb.second) swap(t, sb);
	}
	if (fb.second != col[v]) {
		if (fb.second != -1) {
			ll w = fb.first + d[v] + X[v];
			if (w < bestEdge[col[v]].first) {
				bestEdge[col[v]] = mp(w, fb.second);
			}
		}
	} else {
		if (sb.second != -1) {
			ll w = sb.first + d[v] + X[v];
			if (w < bestEdge[col[v]].first) {
				bestEdge[col[v]] = mp(w, sb.second);
			}
		}
	}
	for (pli e : g[v]) {
		int u = e.second;
		if (u == p) continue;
		dfs2(u, v, fb, sb);
	}
}

void solve() {
	dfs1(0, -1);
	dfs2(0, -1, mp(INF, -1), mp(INF, -1));
}

int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	scanf("%d", &n);
	for (int i = 0; i < n; i++)
		scanf("%lld", &X[i]);
	for (int i = 1; i < n; i++) {
		int v, u;
		ll w;
		scanf("%d%d%lld", &v, &u, &w);
		v--;u--;
		g[v].push_back(mp(w, u));
		g[u].push_back(mp(w, v));
	}
	dfs0(0, -1);

	for (int i = 0; i < n; i++) {
		par[i] = -1;
		sz[i] = 1;
	}

	while(true) {
//		printf("ITER\n");
		allSz = 0;
		for (int v = 0; v < n; v++)
			all[allSz++] = col[v] = getPar(v);
		sort(all, all + allSz);
		allSz = unique(all, all + allSz) - all;
		if (allSz == 1) break;
		for (int i = 0; i < allSz; i++) {
			int v = all[i];
			bestEdge[v] = mp(INF, -1);
		}
		solve();
//		for (int i = 0; i < allSz; i++)
//			printf("%d %d %lld\n", all[i], bestEdge[all[i]].second, bestEdge[all[i]].first);
		for (int i = 0; i < allSz; i++) {
			int v = all[i];
			if (bestEdge[v].second == -1) throw;
			if (unite(v, bestEdge[v].second))
				ANS += bestEdge[v].first;
		}
	}
	printf("%lld\n", ANS);
	return 0;
}


Measured memory_bytes: 52864