#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define REP(i, m, n) for(int i = (m); i < (int)(n); i++)
#define all(x) (x).begin(),(x).end()
#define MOD 1000000007
#define INF (1e9)
#define PI (acos(-1))
#define print(x) cout << x << endl
#define yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define no cout << "No" << endl
#define NO cout << "NO" << endl


int N;
vector<int> _G[10000];
vector<int> G[10000];  // 配列の各要素がvectorとなる
bool used_prov[10000] = {};  // 配列を確保
bool used_sum[10000] = {};  // 配列を確保

pair<int, int> c[10000];  // (c, 番号)
pair<int, pair<int, int>> q[10000];  // (頂点, (c, 番号))
int ans_sum = 0;
int cnt_prov = 1;

void dfs_prov(int cur, int past) {
    // next は 頂点cur と連結している頂点
    for (auto next:G[cur]) {
        // 終了条件
        if (next == past) continue;
        // 何らかの操作
        // 頂点とcのpairを作る
        if (next != 0) q[next] = make_pair(next, make_pair(c[cnt_prov].first, c[cnt_prov].second));
        //cout << c[cnt_prov].first << " " << c[cnt_prov].second << endl;
        cnt_prov++;
        // 足跡
        if (used_prov[next]) continue;
        used_prov[next] = true;
        // next
        dfs_prov(next, cur);
    }
    return;

}

void dfs_sum(int cur, int past) {
    // next は 頂点cur と連結している頂点
    for (auto next:G[cur]) {
        // 終了条件
        if (next == past) continue;
        // 何らかの操作
        // 頂点のうち小さい方をsum
        ans_sum += min(q[cur].second.first, q[next].second.first);
        // 足跡
        if (used_sum[next]) continue;
        used_sum[next] = true;
        // next
        dfs_sum(next, cur);
    }
    return;
}

int main() {

    cin >> N;
    vector<int> a(N);
    vector<int> b(N);
    vector<int> p(N);
    rep(i, N-1) cin >> a[i] >> b[i];
    rep(i, N) cin >> p[i];

    // c を昇順ソート
    rep(i, N) {
        c[i] = make_pair(p[i], i);
    }
    sort(c, c+N);
    reverse(c, c+N);

    rep(i, N-1) {
        // G[i]には頂点iと隣合う全頂点が格納される
        _G[a[i]-1].push_back(b[i]-1);
        _G[b[i]-1].push_back(a[i]-1);
    }

    bool flag = false;
    int pos;
    if (_G[0].size() == 1) flag = true;
    else {
        rep(i, N) {
            if (_G[i].size() == 1) {
                pos = i;
            }
        }
    }

    if (!flag) {
        rep(i, a.size()) {
            if (a[i] == pos) a[i] = 0;
            if (a[i] == 0) a[i] = pos;
            if (b[i] == pos) b[i] = 0;
            if (b[i] == 0) b[i] = pos;
        } 
    }

    rep(i, N-1) {
        // G[i]には頂点iと隣合う全頂点が格納される
        G[a[i]-1].push_back(b[i]-1);
        G[b[i]-1].push_back(a[i]-1);
    }

    q[0] = make_pair(0, make_pair(c[0].first, c[0].second));

    // 全頂点を探索
    rep(i, N) {
        // 足跡なければ
        if (used_prov[i] == false) {
            // 探索
            dfs_prov(i, -1);
        }
    }

    // 全頂点を探索
    rep(i, N) {
        // 足跡なければ
        if (used_sum[i] == false) {
            // 探索
            dfs_sum(i, -1);
        }
    }

    pair<int, int> d[N];  // (頂点，c)
    rep(i, N) {
        d[i] = make_pair(q[i].first, q[i].second.first);
    }
    sort(d, d+N);

    print(ans_sum);
    rep(i, N) cout << d[i].second << " ";

}



Measured memory_bytes: 2176