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++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>
using namespace std;
#define LL long long
int n;
const int N = 300000;
const LL INF = 1e16;
#define pI pair <LL, int>
#define fr first
#define sc second
#define mp make_pair
int xi[N];
vector <int> bi[N], ci[N];
int fp[N];
int get_fp(int a)
{
    if (fp[a] == a) return a;
    else return fp[a] = get_fp(fp[a]);
}
struct PP
{
    pI a, b;
} O, edge[N], F[N], tmp[N];
LL ans;
PP merge(PP x, PP y)
{
    PP z;
    if (x.a > y.a) swap(x, y);
    z.a = x.a;
    if (x.a.sc == y.a.sc)
        if (x.a.sc == y.b.sc)
            z.b = x.b;
        else if (x.b < y.b)
            z.b = x.b;
        else z.b = y.b;
    else if (x.b < y.a)
        z.b = x.b;
    else z.b = y.a;
    return z;
}
PP ADD(PP x, int v)
{
    return (PP){mp(x.a.fr + v, x.a.sc), mp(x.b.fr + v, x.b.sc)};
}
PP dfs1(int t, int f)
{
    F[t] = O; F[t].a = mp(xi[t], get_fp(t));
    for (int i = 0; i < bi[t].size(); ++ i)
        if (bi[t][i] != f)
        {
            PP res = ADD(dfs1(bi[t][i], t), ci[t][i]);
            F[t] = merge(F[t], res);
        }
    edge[get_fp(t)] = merge(edge[get_fp(t)], ADD(F[t], xi[t]));
    return F[t];
}
void dfs2(int t, int f, PP u)
{
    edge[get_fp(t)] = merge(edge[get_fp(t)], ADD(u, xi[t]));
    tmp[bi[t].size()] = O;
    for (int i = bi[t].size() - 1; ~i; -- i)
    {
        tmp[i] = tmp[i + 1];
        if (bi[t][i] != f) tmp[i] = merge(tmp[i], ADD(F[bi[t][i]], ci[t][i]));
    }
    PP p = O; p.a = mp(xi[t], get_fp(t));
    for (int i = 0; i < bi[t].size(); ++ i)
        if (bi[t][i] != f)
        {
            dfs2(bi[t][i], t, ADD(merge(merge(u, p), tmp[i + 1]), ci[t][i]));
            p = merge(p, ADD(F[bi[t][i]], ci[t][i]));
        }
}
int C;
int main()
{
    O = (PP){mp(INF, -1), mp(INF, -2)};
    scanf("%d", &n);
    for (int i = 1; i <= n; ++ i) scanf("%d", &xi[i]);
    for (int i = 1; i < n; ++ i)
    {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        bi[a].push_back(b); ci[a].push_back(c);
        bi[b].push_back(a); ci[b].push_back(c);
    }
    for (int i = 1; i <= n; ++ i) fp[i] = i;
    while (C < n - 1)
    {
        for (int i = 1; i <= n; ++ i) edge[i] = O;
        dfs1(1, 0);
        dfs2(1, 0, O);
        for (int i = 1; i <= n; ++ i) if (fp[i] == i)
        {
            pI w;
            if (edge[i].a.sc == i) w = edge[i].b;
            else w = edge[i].a;
            if (get_fp(w.sc) != get_fp(i))
            {
                fp[i] = w.sc;
                ans += w.fr;
                C ++;
            }
        }
    }
    printf("%lld\n", ans);
}