Problem:
Score : 1900 points

Problem Statement

Ringo has a tree with N vertices.
The i-th of the N-1 edges in this tree connects Vertex A_i and Vertex B_i and has a weight of C_i.
Additionally, Vertex i has a weight of X_i.

Here, we define f(u,v) as the distance between Vertex u and Vertex v, plus X_u + X_v.

We will consider a complete graph G with N vertices.
The cost of its edge that connects Vertex u and Vertex v is f(u,v).
Find the minimum spanning tree of G.

Constraints

2 \leq N \leq 200,000

1 \leq X_i \leq 10^9

1 \leq A_i,B_i \leq N

1 \leq C_i \leq 10^9

The given graph is a tree.

All input values are integers.

Input

Input is given from Standard Input in the following format:

N
X_1 X_2 ... X_N
A_1 B_1 C_1
A_2 B_2 C_2
:
A_{N-1} B_{N-1} C_{N-1}

Output

Print the cost of the minimum spanning tree of G.

Sample Input 1

4
1 3 5 1
1 2 1
2 3 2
3 4 3

Sample Output 1

22

We connect the following pairs: Vertex 1 and 2, Vertex 1 and 4, Vertex 3 and 4. The costs are 5, 8 and 9, respectively, for a total of 22.

Sample Input 2

6
44 23 31 29 32 15
1 2 10
1 3 12
1 4 16
4 5 8
4 6 15

Sample Output 2

359

Sample Input 3

2
1000000000 1000000000
2 1 1000000000

Sample Output 3

3000000000

Solution in C++ (GCC 9.2.1) (judge verdict: Runtime Error)

#include<stdio.h>
#include<vector>
#include<algorithm>
#define LL long long
using namespace std;
const int maxn=200005;
const int inf=1<<30;


struct NODE
{
	int u;
	LL cost;
	bool operator<(const NODE&v)
	{
		return cost<v.cost;
	}
}d[maxn];

struct Edge{
	int from,to;
	LL w;
	
	bool operator<(const Edge&v)
	{
		return w<v.w;
	}
};

vector<Edge>g[maxn];
int f[maxn],siz[maxn],rt,tot,cnt,del[maxn],w[maxn];
//f数组存储最大孩子，size是子树大小， 
void Getroot(int x,int fa)
{
	f[x]=0,siz[x]=1;
	for(int i=0;i<g[x].size();i++)
	{
		Edge&e=g[x][i];
		if(del[e.to]||e.to==fa) continue;
		Getroot(e.to,x);
		f[x]=max(f[x],siz[e.to]);
		siz[x]+=siz[e.to];
	}
//	printf("x=%d f=%d sz=%d\n",x,f[x],siz[x]);
	f[x]=max(f[x],tot-siz[x]);//f[0]=0
	if(f[x]<f[rt]) rt=x;
} 


struct MST
{
	Edge edge[maxn*40];
	int p[maxn],ecnt;
	int find(int x){return x==p[x]?x:p[x]=find(p[x]);}
	void Addedge(int u,int v,LL w) { edge[ecnt++]=Edge{u,v,w};}
	bool Union(int x,int y)
	{
		int px=find(x),py=find(y);
		if(px!=py)
			{
				p[px]=py;
				return true;
			}
		else 
			return false;
	}
		
	
LL kruskal(int n)
{
	LL ans=0;
	for(int i=1;i<=n;i++) p[i]=i;
	sort(edge,edge+ecnt);
	for(int i=0;i<ecnt;i++)
	{
		if(Union(edge[i].from,edge[i].to))
			ans+=edge[i].w;
	}
	return ans;
}
	
}mst;


void getnum(int o,int fa,LL D)
{
	d[cnt++]=NODE{o,D+w[o]};
	for(int i=0;i<g[o].size();i++)
	{
		Edge&e=g[o][i];
		if(del[e.to]||e.to==fa) continue;
		getnum(e.to,o,D+e.w);
	}	
}

void getans(int o)
{
	cnt=0;
	getnum(o,-1,0);
	sort(d,d+cnt);
	for(int i=1;i<cnt;i++)
		mst.Addedge(d[0].u,d[i].u,d[0].cost+d[i].cost);
}


void solve(int o)
{
	del[o]=1,getans(o);
	for(int i=0;i<g[o].size();i++)
	{ 
		Edge&e=g[o][i]; 
		if(del[e.to]) continue;
		tot-=siz[e.to],rt=0;
		Getroot(e.to,o),solve(rt);
	} 	
}



int main(){
  //  freopen("C:\\Users\\deii\\Desktop\\test.txt","r",stdin);	
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&w[i]);
	for(int i=0;i<n-1;i++)
	{
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);
		g[u].push_back(Edge{u,v,w});
		g[v].push_back(Edge{v,u,w});	
	}
	f[0]=inf;
	tot=n,rt=0;
	mst.ecnt=0;
	Getroot(1,-1);
	solve(rt);
	printf("%lld",mst.kruskal(n));
	
	return 0;
}