/*input
4
1 3 5 1
1 2 1
2 3 2
3 4 3
*/
#include <bits/stdc++.h>
using namespace std;

#define uint unsigned int

const int N = 400005;
const uint inf = 3e9 + 1;

int read() {
	int x = 0, c = getchar();
	for(; !(c > 47 && c < 58); c = getchar());
	for(; (c > 47 && c < 58); c = getchar()) x = x * 10 + c - 48;
	return x;
}

struct Edge {
	int u, v, w;
	Edge(int _u = 0, int _v = 0, int _w = 0):
		u(_u), v(_v), w(_w) {}

	int to(int x) {
		return u + v - x;
	}
} edge[N];

vector<Edge> binTree;
vector<int> G[N]; // edge id of the tree

int n;
int value[N];

void pre_dfs(int u, int p) {
	for(int i = 0; i < (int)G[u].size(); ++ i) {
		int id = G[u][i], v = edge[id].to(u);
		if(v == p) {
			swap(G[u][i], G[u].back()), G[u].pop_back(), -- i;
		} else pre_dfs(v, u);
	}
}

// start of the centroid
int del[N];
int partOfMst[N];

typedef pair<uint, int> uwu;
set<uwu> candidates;

// helper centroid variables
vector<uwu> rootsOf[N];
vector<uwu> nodes[2][N];
int curP[2][N];

int subt[N];

void dfs(int u, int p) {
	subt[u] = 1;
	for(auto id : G[u]) {
		int v = binTree[id].to(u);
		if((v == p) || del[id]) continue;
		dfs(v, u), subt[u] += subt[v];
	}
}

int findCen(int u, int p, int sz) {
	for(auto id : G[u]) {
		int v = binTree[id].to(u);
		if((v == p) || del[id]) continue;
		if(subt[v] > sz / 2) return findCen(v, u, sz);
	}
	return u;
}

int findEdge(int u, int sz) {
	int diff = 2e9, idx = -1;
	for(auto id : G[u]) {
		int v = binTree[id].to(u);
		if((!del[id]) && abs(subt[v] * 2 - sz) < diff) diff = abs(subt[v] * 2 - sz), idx = id;
	}
	return idx;
}

long long h[N];

void push(int u, int p, int c) {
	if(u < n) {
		if(h[u] + value[u] < inf) {
			rootsOf[u].emplace_back(uwu(h[u] + value[u], c)),
			nodes[c < 0][abs(c)].emplace_back(uwu(h[u] + value[u], u));
		}
	}
	for(auto id : G[u]) {
		int v = binTree[id].to(u);
		if(v == p || del[id]) continue;
		h[v] = h[u] + binTree[id].w;
		push(v, u, c);
	}
}

void build(int u) {
	dfs(u, u), u = findCen(u, u, subt[u]), dfs(u, u);
	if(subt[u] == 1) return;

	int id = findEdge(u, subt[u]);
	Edge e = binTree[id];
	assert(id);

	del[id] = 1;
	h[e.u] = h[e.v] = 0;
	push(e.u, e.u, id), push(e.v, e.v, -id);
	build(e.u), build(e.v);
}

uint dis[N];
uint bestG[2][N];

// this means u is the curBest in some centroid
void mergeVertice(int u) {
	partOfMst[u] = 1;
	for(auto cur : rootsOf[u]) {
		int c = cur.second < 0, id = abs(cur.second);
		uint len = cur.first;

		if(len < bestG[c][id]) {
			bestG[c][id] = len;

			int &i = curP[c ^ 1][id];

			for(; partOfMst[nodes[c ^ 1][id][i].second]; ++ i);

			if(nodes[c ^ 1][id][i].second < n) {
				uwu cur = nodes[c ^ 1][id][i];
				if(0ll + len + cur.first + binTree[id].w < dis[cur.second]) {
					candidates.erase(uwu(dis[cur.second], cur.second));

					dis[cur.second] = len + cur.first + binTree[id].w;

					candidates.insert(uwu(dis[cur.second], cur.second));
				}
			}
		}
		
		if(bestG[c ^ 1][id] < inf) {
			int &i = curP[c][id];
			for(; partOfMst[nodes[c][id][i].second]; ++ i);
			if(nodes[c][id][i].second < n) {
				uwu cur = nodes[c][id][i];
				if(0ll + cur.first + bestG[c ^ 1][id] + binTree[id].w < dis[cur.second]) {
					candidates.erase(uwu(dis[cur.second], cur.second));

					dis[cur.second] = cur.first + binTree[id].w + bestG[c ^ 1][id];

					candidates.insert(uwu(dis[cur.second], cur.second)); 
				}
			}
		}
	}
}

// end of centroid
int treeSize;
long long Ans = 0;

int main(){
	n = read();
	for(int i = 0; i < n; value[i ++] = read());
	for(int i = 1; i < n; ++ i) {
		int u = read() - 1, v = read() - 1, w = read();
		edge[i] = Edge(u, v, w);
		G[u].emplace_back(i);
		G[v].emplace_back(i);
	}
	pre_dfs(0, 0);

	treeSize = n - 1;
	binTree.emplace_back(Edge(0, 0, 0));
	for(int u = 0; u < n; ++ u)
		if(G[u].size() > 2) {	
			int m = (int)G[u].size();
			// label the nodes of the current nodes from m to (m << 1) - 1
			// parent of node i should be i / 2, if i / 2 == 1 then the parent of i should be u
			for(int i = 0; i < m; ++ i) {
				int id = G[u][i], v = edge[id].to(u), x = treeSize + ((i + m) / 2);
				if(x == treeSize + 1) binTree.emplace_back(Edge(v, u, edge[id].w));
					else binTree.emplace_back(Edge(v, x, edge[id].w));
			}
			for(int i = 2; i < m; ++ i)
				if(i / 2 > 1) binTree.emplace_back(Edge(treeSize + i, treeSize + i / 2, 0));
					else binTree.emplace_back(Edge(treeSize + i, u, 0));

			treeSize += m - 1;
		} else for(auto id : G[u]) binTree.emplace_back(Edge(edge[id].to(u), u, edge[id].w));

	for(int i = 0; i < n; ++ i) G[i].clear();
	for(int i = 1; i < (int)binTree.size(); ++ i) {
		int u = binTree[i].u, v = binTree[i].v;
		G[u].emplace_back(i);
		G[v].emplace_back(i);
	}

	build(0);
	for(int j = 0; j < 2; ++ j)
		for(int i = 1; i < (int)binTree.size(); ++ i) {
			bestG[j][i] = inf;
			nodes[j][i].emplace_back(uwu(inf, n));
			sort(nodes[j][i].begin(), nodes[j][i].end());
		}

	for(int i = 1; i < n; ++ i) dis[i] = inf;
	for(int i = 0; i < n; ++ i) candidates.insert(uwu(dis[i], i));

	for(int cnt = 0; cnt < n; ++ cnt) {
		int u = (*candidates.begin()).second;
		uint len = (*candidates.begin()).first;

		candidates.erase(candidates.begin());

		// cout << u << ' ' << len << endl;
		mergeVertice(u);
		Ans += len;
	}
	printf("%lld\n", Ans);
	// cerr << fixed << setprecision(6) << (double)clock() / CLOCKS_PER_SEC << endl;
}

Measured memory_bytes: 210152