/*
    
    一棵树n<=180,树上每条边的长度都是1,若两点的距离为len,则他们通信的代价就是d[len]
    d[]是给出的
    可以选一些点建立Information Reform,这些点可自动获取信息,建立一个这样的点代价为k
    其他没建的点就会与最近的Information Reform通信,以获取信息
    求使得树上所有点都能获取信息的最小代价,以及它们各自要通信的Information Reform

    不会做.看了解题报告还是一头雾水,知道需要O(n^3)的树形dp
    看别人代码的
    dp[u,c]表示u的这棵子树,其中u以c为Information Reform的最小代价,但u的子树上的
    其他点不一定以c为Information Reform
    则dp[u,c] = cost[u,v] + ∑min{dp[v,c], dp[v,center[v]] + k}   
    center[u],它是使u这棵子树所有点获得信息的最小代价的Information Reform

    注意的是center[u]是指使u这棵子树所有点能获得信息的最小代价,不一定是最后的答案
    所以输出答案时,可以自顶向下,比如0的肯定是center[0],然后利用之前的转移
        dp[u,c] = cost[u,v] + ∑min{dp[v,c], dp[v,c'] + k}  
    去更新子树实际的center[v]
    if dp[v,center[u]] < dp[v,center[v]] + k 
        center[v] = c

    第一次遇到这样的树形dp,在考虑某棵子树时,影响它代价的可以是整棵树(如这里可以以u子树外
    的点为Information Reform)                                       ------------------OMG
*/

#include
<iostream>
#include
<cstring>
#include
<map>
#include
<algorithm>
#include
<stack>
#include
<queue>
#include
<cmath>
#include
<string>
#include
<cstdlib>
#include
<vector>
#include
<cstdio>
#include
<set>
#include
<list>
#include
<numeric>
#include
<cassert>
#include
<ctime>
#include
<bitset>

using namespace std;

const int MAXN = 200;
const int INF = 0x3f3f3f3f;

vector
<int> e[MAXN];
int w[MAXN][MAXN], d[MAXN];
int center[MAXN], dp[MAXN][MAXN];
int n, k;

void floyd() {
    
for (int k = 0 ; k < n; k++{
        
for (int i =  0; i < n ; i ++{
            
if(w[i][k] == INF) {
                
continue;
            }

            
for (int j = 0 ; j < n; j++{
                
if(w[k][j] == INF) {
                    
continue;
                }

                w[i][j] 
= min(w[i][j], w[i][k] + w[k][j]);
            }

        }

    }

}


void dfs(int u, int p) {
    
for (vector<int>::iterator it = e[u].begin() ; it != e[u].end(); it++{
        
int v = *it;
        
if(v != p){
            dfs(v, u);
        }

    }

    center[u] 
= 0;
    
for (int f = 0; f < n ; f ++{
        dp[u][f] 
= d[w[u][f]];
        
for (vector<int>::iterator it = e[u].begin(); it != e[u].end(); it++{
            
int v = *it;
            
if(v != p) {
                dp[u][f] 
+= min(dp[v][f], dp[v][center[v]] + k);
            }

        }

        
if(dp[u][f] < dp[u][center[u]]) {
            center[u] 
= f;
        }

    }

}


void retrieve(int u, int p) {
    
for (vector<int>::iterator it = e[u].begin() ; it != e[u].end(); it++{
        
int v = *it;
        
if(v != p) {
            
int f = center[u];
            
if(dp[v][f] < dp[v][center[v]] + k) {
                center[v] 
= f;
            }

            retrieve(v, u);
        }

    }

}


int main()
{
#ifndef ONLINE_JUDGE
    freopen(
"in","r",stdin);
#endif
    
    
for (; ~scanf("%d%d"&n, &k); ) {
        fill(w[
0], w[n], INF);
        
for (int i = 0 ; i < n ; i ++ ){
            e[i].clear();
            w[i][i] 
= 0;
        }

        
for (int i = 1 ; i < n ; i ++{
            scanf(
"%d"&d[i]);
        }

        
for (int i = 1,u,v; i <n; i++{
            scanf(
"%d%d"&u, &v);
            u
--;
            v
--;
            e[u].push_back(v);
            e[v].push_back(u);
            w[u][v] 
= w[v][u] = 1;
        }

        floyd();
        dfs(
0,0);
        retrieve(
0,0);
        printf(
"%d\n", dp[0][center[0]] + k);//还要加上k
        for (int i = 0 ; i < n ; i ++{
            
if (i >0){
                putchar(
' ');
            }

            printf(
"%d", center[i] + 1);
        }

        puts(
"");
    }

    
return 0;
}