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 (Clang 3.8.0) (judge verdict: Wrong Answer)

#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <utility>
#include <queue>
#include <set>
#include <map>
#include <deque>
#include <iomanip>
#include <cstdio>
#include <stack>
#include <numeric>

using namespace std;
typedef  long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<VI> VVI;
#define  MP make_pair
#define  PB push_back
#define inf  1000000007
#define rep(i,n) for(int i=0;i<(int)(n);++i)

class UnionFind {
private:
    int sz;
    vector<int> par, nrank;
public:
    UnionFind(){}
    UnionFind(int node_size) : sz(node_size), par(sz), nrank(sz, 0){
        iota(par.begin(), par.end(), 0);
    }
    int find(int x){
        if(par[x] == x) return x;
        else return par[x] = find(par[x]);
    }
    void unite(int x,int y){
        x = find(x), y = find(y);
        if(x == y) return;
    	if(nrank[x] < nrank[y]) swap(x,y);
        par[y] = x;
        if(nrank[x] == nrank[y]) nrank[x]++;
    }
    bool same(int x,int y){
        return find(x) == find(y);
    }
};
 


pair<pair<ll,int>,pair<ll,int> > dp1[200010];
pair<pair<ll,int>,pair<ll,int> > dp2[200010];
vector<ll> x;
vector<int> q;
vector<vector<pair<int,ll> > >g;

pair<pair<ll,int>,pair<ll,int> > merge(pair<pair<ll,int>,pair<ll,int> >a,pair<pair<ll,int>,pair<ll,int> >b){
    vector<pair<ll,int> > s;
    s.PB(a.first);
    s.PB(a.second);
    s.PB(b.first);
    s.PB(b.second);
    sort(s.begin(),s.end());
    if(s[0].second==s[1].second){
        return MP(s[0],s[2]);
    }else{
        return MP(s[0],s[1]);
    }
}
pair<pair<ll,int>,pair<ll,int> > merge(pair<pair<ll,int>,pair<ll,int> >a,pair<ll,int> b){
    if(a.first.second==b.second){
        if(b.first>a.first.first){
            return a;
        }else{
            return MP(b,a.second);
        }
    }else{
        if(b.first<a.first.first){
            return MP(b,a.first);
        }else{
            if(b.first<a.second.first){
                return MP(a.first,b);
            }else{
                return a;
            }
        }
    }
}
pair<pair<ll,int>,pair<ll,int> > dfs(int a,int pre){
    pair<pair<ll,int>,pair<ll,int> > tmp;
    tmp.first = MP((1LL<<50),-1);
    tmp.second = MP((1LL<<50),-1);
    for(auto p:g[a]){
        if(p.first!=pre){
            pair<pair<ll,int>,pair<ll,int> > s = dfs(p.first,a);
            s.first.first += p.second;
            s.second.first += p.second;
            tmp = merge(tmp,s);
        }
    }
    dp1[a] = tmp;
    return merge(dp1[a],MP(x[a],q[a]));
}
void dfs2(int a,int pre,ll val){
    pair<pair<ll,int>,pair<ll,int> > tmp = dp1[a];
    if(pre!=-1){
        tmp = merge(tmp,MP(x[pre]+val,q[pre]));
        auto s = dp2[pre];
        s.first.first += val;
        s.second.first += val;
        tmp = merge(tmp,s);
    }
    dp2[a] = tmp;
    for(auto p:g[a]){
        if(p.first!=pre){
            dfs2(p.first,a,p.second);
        }
    }
}

int main(){
    int n;
    cin >> n;
    x.resize(n);
    g.resize(n);
    rep(i,n)cin >> x[i];
    rep(i,n-1){
        int a,b;
        ll c;
        cin >> a >> b >> c;
        a--;b--;
        g[a].PB(MP(b,c));
        g[b].PB(MP(a,c));
    }
    UnionFind uf(n);
    q.resize(n);
    rep(i,n){
        q[i] = i;
    }
    ll ans = 0;
    while(1){
        dfs(0,-1);
        dfs2(0,-1,0);
        vector<pair<pair<ll,int>,pair<ll,int> > >r(n,MP(MP(1LL<<60,-1),MP(1LL<<60,-1)));
        rep(i,n){
            if(q[i]!=dp2[i].first.second){
                r[q[i]] = merge(r[q[i]],MP(dp2[i].first.first+x[i],dp2[i].first.second));
            }else{
                r[q[i]] = merge(r[q[i]],MP(dp2[i].second.first+x[i],dp2[i].second.second));
            }
        }
        rep(i,n){
            //cerr << i << " " << q[i] << " " << " " << r[i].first.second << " " << r[i].second.second  << endl;
            if(r[i].first.second!=-1&&!uf.same(i,r[i].first.second)){
                //cerr << i << " " << r[i].second << " " << r[i].first << endl;
                ans += r[i].first.first;
                uf.unite(i,r[i].first.second);
            }else{
                if(r[i].second.second!=-1&&!uf.same(i,r[i].second.second)){
                    ans += r[i].second.first;
                    uf.unite(i,r[i].second.second);
                }
            }
        }
        bool flag = 1;
        rep(i,n){
            q[i] = uf.find(i);
            if(q[0]!=q[i]){
                flag = 0;
            }
            //cerr << q[i] << " ";
        }
        //cerr << endl;
        //if(cnt==3)break;
        if(flag)break;
    }
    cout << ans << endl;
    return 0;
}