/*
    題意:一棵樹上,每個(gè)節(jié)點(diǎn)有cnt[i]個(gè)人  每條邊有權(quán)值
           現(xiàn)要求一個(gè)點(diǎn),使得其他點(diǎn)到該點(diǎn)的所有代價(jià)最小
           代價(jià)即 ∑人數(shù)*經(jīng)過邊的權(quán)值

    tree dp 自底向上 自頂向下更新2次即可

    先dfs1求得:
    ans[u]  以u為根的子樹,所有點(diǎn)到u的代價(jià)
    sum[u]  u及其子樹所有節(jié)點(diǎn)的人數(shù)
    同時(shí)記錄父邊的權(quán)值preE[u]

    再dfs2來更新得到正確的ans[u](即整棵樹以u為目標(biāo)節(jié)點(diǎn)的代價(jià))
    即:ans[u]=ans[p]-sum[u]*preE[u]+(tot-sum[u])*preE[u];
    這時(shí)ans[p]保存的是所有點(diǎn)到p的代價(jià),當(dāng)然包括從u的及其子樹到p的代價(jià),所以要減去
    +除u的子樹外的所有節(jié)點(diǎn)到達(dá)u的代價(jià)

    跟hdu 2196  poj 3585  CII 4614 一樣,2次dfs
*/

#include
<cstdio>
#include
<cstring>
#include
<algorithm>
#include
<vector>

using namespace std;

const int MAXN = 100010;

vector
<pair<int,int> >G[MAXN];

long long ans[MAXN],sum[MAXN];
long long tot;
int preE[MAXN],cnt[MAXN];

void dfs1(int u,int p)
{
    sum[u]
=cnt[u];
    ans[u]
=0;
    
for(int i=0,size=G[u].size();i<size;i++)
    
{
        
int v=G[u][i].first,c=G[u][i].second;
        
if(v==p)continue;
        dfs1(v,u);
        preE[v]
=c;
        sum[u]
+=sum[v];
        ans[u]
+=(ans[v]+sum[v]*c);
    }

}

void dfs2(int u,int p)
{
    
if(u!=1)
    
{
        ans[u]
=ans[p]-sum[u]*preE[u]+(tot-sum[u])*preE[u];
    }

    
for(int i=0,size=G[u].size();i<size;i++)
    
{
        
int v=G[u][i].first;
        
if(v==p)continue;
        dfs2(v,u);
    }

}

int main()
{

    
int n;
    
int a,b,c;
    
while(~scanf("%d",&n))
    
{
        tot
=0;
        
for(int i=1;i<=n;i++)
        
{
            G[i].clear();
            scanf(
"%d",&cnt[i]);
            tot
+=cnt[i];
        }

        
for(int i=1;i<n;i++)
        
{
            scanf(
"%d%d%d",&a,&b,&c);
            G[a].push_back(make_pair(b,c));
            G[b].push_back(make_pair(a,c));
        }

        preE[
1]=0;
        dfs1(
1,0);
        dfs2(
1,0);
        printf(
"%lld\n",*min_element(ans+1,ans+1+n));
    }

    
return 0;
}