#include <bits/stdc++.h>
using namespace std;

#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define MIN(a) *min_element(all(a))
#define MAX(a) *max_element(all(a))
#define SUM(a, b) accumulate(all(a), b)
#define REP(i, n) for(int (i)=0; (i)<(n); (i)++)
#define RREP(i, n) for(int (i)=(n)-1; (i)>=0; (i)--)
#define FOR(i, m, n) for(int (i)=(m); (i)<(n); i++)
#define FORR(i, m, n) for(int (i)=(n)-1; (i)>=(m); i--)
#define ios() cin.tie(0), ios::sync_with_stdio(false)
#define debug(x) cerr << #x << " = " << x << endl
//#define int long long

typedef long long ll;
typedef unsigned long long ull;
//ll const MOD = 998244353;
ll const MOD = 1e9+7;
ll const INF = 1e18;

template<typename T> int size(const T& a){return (int)a.size();}
template<typename T> T Div(T a, T b){return (a + b - 1) / b;}
template<typename T> bool chmin(T& a, const T& b){if(a > b){a = b; return true;} return false;}
template<typename T> bool chmax(T& a, const T& b){if(a < b){a = b; return true;} return false;}

//Graph in adjcency list
class Graph{
    typedef pair<int,ll> edge;
public:
    int N;  //頂点数
    vector<vector<edge>> adjlist;   //隣接リスト
    vector<ll> depth;   //ノードの深さ
    vector<bool> check; //訪問済みの頂点を記録
    ll diam;            //木の直径
    vector<int> deg;    //入次数
    vector<int> tsort;  //トポロジカルソートの結果
    vector<ll> c;

    Graph(int n) : N(n), adjlist(n), depth(n, INF), check(n, false), diam(INF), deg(n, 0){}

    void setEdge(int a, int b, ll c){   //辺を追加
        adjlist[a].push_back(make_pair(b, c));
        deg[b]++;
    }

    void input(){
        c.resize(N);
        REP(i, N){
            cin >> c[i];
        }
        sort(rall(c));
    }

    void dfs(int p, int v, ll d){    //深さ優先探索
        static int x = 0;
        if(check[v]) return;

        check[v] = true;
        depth[v] = c[x];
        x++;

        for(auto i : adjlist[v]){
            if(i.first == p) continue;
            dfs(v, i.first, d + i.second);
        }
    }

    void bfs(int v){        //幅優先探索
        queue<edge> que;
        for(auto i : adjlist[v]) que.push(i);

        check[v] = true;

        while(!que.empty()){
            int u = que.front().first;
            ll d = que.front().second;
            que.pop();

            check[u] = true;
            depth[u] = d;

            for(auto i : adjlist[u]){
                if(!check[i.first]){
                    que.push(make_pair(i.first, d + i.second));
                }
            }
        }
    }

    ll diameter(){  //木の直径を求める
        if(diam != INF) return diam;  //計算済みの場合

        dfs(-1, 0, 0);  //頂点0からの最遠頂点vを求める
        int v = max_element(all(depth)) - depth.begin();

        REP(i, N){
            check[i] = false;
            depth[i] = 0;
        }

        dfs(-1, v, 0);  //vからの最遠頂点を求める

        return diam = MAX(depth);   //この2頂点間の距離が直径
    }

    void dijkstra(int start){   //ダイクストラ法
        depth[start] = 0;

        auto fn = [](edge a, edge b){return a.second > b.second;};
        priority_queue<edge, vector<edge>, decltype(fn)> que(fn);

        for(auto i : adjlist[start]) que.push(i);

        while(!que.empty()){
            auto v = que.top().first;
            auto d = que.top().second;
            que.pop();

            if(depth[v] < INF) continue;
            else depth[v] = d;
            
            for(auto i : adjlist[v]){
                if(depth[i.first] == INF){
                    que.push(make_pair(i.first, i.second + d));
                }
            }
        }
    }

    bool BellmanFord(int start){    //ベルマンフォード法 (負の閉路がある場合はtrueを返す)
        depth[start] = 0;
        REP(i, N){
            REP(j, N){
                for(auto k : adjlist[j]){
                    if(check[j] && depth[j] + k.second < depth[k.first]){
                        if(i == N-1) return true;  //N回目にも更新があるなら負の閉路が存在
                        depth[k.first] = depth[j] + k.second;
                    }
                }
            }
        }
        return false;
    }

    void topologicalSort(){ //トポロジカルソート
        deque<int> deq;
        REP(i, N){
            if(deg[i] == 0) deq.push_back(i);
        }

        while(!deq.empty()){
            auto v = deq.front();
            deq.pop_front();
            tsort.push_back(v);
            for(auto i : adjlist[v]){
                deg[i.first]--;
                if(deg[i.first] == 0) deq.push_back(i.first);
            }
        }
    }
};


signed main(){
    int n;
    cin >> n;

    vector<pair<int,int>> deg(n);
    REP(i, n) deg[i].first = i;

    Graph G(n);

    REP(i, n-1){
        int a, b;
        cin >> a >> b;
        G.setEdge(a-1, b-1, 1);
        G.setEdge(b-1, a-1, 1);
        deg[a-1].second++;
        deg[b-1].second++;
    }

    G.input();
    sort(all(deg), [](auto a, auto b){return a.second > b.second;});

    int root = deg[0].first;
    G.dfs(-1, root, 0);

    cout << SUM(G.c, 0LL) - G.c[0] << endl;

    REP(i, n){
        cout << G.depth[i] << " \n"[i == n-1];
    }

    return 0;
}


Measured memory_bytes: 1664