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

#define int long long
#define vvi vector<vector<int>>
#define vec vector
#define pq priority_queue
#define all(v) (v).begin(), (v).end()
#define uniqueV(x) sort(x.begin(), x.end()); x.erase(unique(x.begin(), x.end()), x.end());
#define rep(i, n) for (int (i) = (0); (i) < (n); ++(i))
#define repp(i, m, n) for (int (i) = (m); (i) < (n); ++(i))
#define dbg(x) cerr << #x << ": " << x << endl;
#define dbg2(x, y) cerr<<"("<<#x<<", "<<#y<<") = "<<"("<<x<<", "<<y<<")"<<endl;
#define dbg3(x, y, z) cerr<<"("<<#x<<", "<<#y<<", "<<#z<<") = "<<"("<<x<<", "<<y<<", "<<z<<")"<<endl;
#define dbgB(value, size) cerr<<#value<<": "<<bitset<size>(value) << endl;
#define line() cerr << "---------------" << endl;

const int dx[] = {1, -1, 0, 0};
const int dy[] = {0, 0, -1, 1};
const double PI = 3.14159265358979323846;

template<class T>bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a = b; return 1; } return 0; }

template<typename T>
void print1(T begin, T end) {
	while (begin != end) {
		cerr << (*begin) << " ";
		*begin++;
	}
	cerr << endl;
}

template<typename T>
void print2(T Array, int height, int width) {
	for (int i = 0; i < height; i++) {
		for (int j = 0; j < width; j++) {
			cerr << " " << Array[i][j];
		}
		cerr << endl;
	}
}

void print() { std::cerr << endl; }
template <class Head, class... Tail>
void print(Head&& head, Tail&&... tail) {
	std::cerr << head << " ";
	print(std::forward<Tail>(tail)...);
}

template<class T>
void Add(T &a, const T &b, const T &mod=1000000007) {
	int val = ((a % mod) + (b % mod)) % mod;
	if (val < 0) { val += mod; }
	a = val;
}

template <typename X, typename T> auto vectors(X x, T a) { return vector<T>(x, a); }
template <typename X, typename Y, typename Z, typename... Zs> auto vectors(X x, Y y, Z z, Zs... zs) { auto cont = vectors(y, z, zs...); return vector<decltype(cont)>(x, cont); }

// ------------------------------------------------------------------------------------------

using pii = pair<int, int>;

int N;

const int maxV = 11111;
vector<int> G[maxV]; // 頂点情報のみのグラフ
int c[11111];
map<pii, int> mp;
// vec<pii> v;
int A[111111];
queue<int> q;
int d[111111];

// 木のDFS
void treeDFS1(int from, int current) {
	int que = q.front(); q.pop();
	// int score = min(c[from], c[current]);
	// mp[{from, current}] = que;
	d[current] = que;
	int score = min(d[from], d[current]);
	mp[{from, current}] = score;
	// v.push_back({current, score});
  for (auto to : G[current]) {
    // 逆流を防ぐ
    if (to == from) continue;
		// int score = min(c[from], c[to]);
		// dbg3(from, to, score)
    treeDFS1(current, to);
  }
}

// 木のDFSを呼び出す関数
void searchTree(int start) {
  int root = start; // 根
  int from = -1; // 根の親。根の親はないので-1を指定する

	sort(c, c+N);
	reverse(c, c+N);
	// キューを用意
	rep (i, N) {
		q.push(c[i]);
	}

	// 頂点にスコアを決める
	treeDFS1(from, root);

	int sum = 0;
	for (auto x : mp) {
		int from = x.first.first, current = x.first.second;
		int score = x.second;
		// dbg3(from, current, score)
		sum += score;
	}
	dbg(sum)
	cout << sum << endl;
	rep (i, N-1) {
		cout << d[i] << " ";
	}
	cout << d[N-1] << endl;

/*
	sort(c, c+N);
	reverse(c, c+N);
	mp.clear();
	treeDFS(from, root);
	int sum = 0;
	for (auto x : mp) {
		int from = x.first.first, current = x.first.second;
		int score = x.second;
		dbg3(from, current, score)
		sum += score;
	}
	line()

	dbg(sum)
	return sum;
	*/

/*
	treeDFS(from, root);
	int sum = 0;
	vec<int> cand(N, 1e18);
	map<int, int> min;
	rep (i, N) {
		min[c[i]]++;
	}
	for (auto x : mp) {
		int from = x.first.first, current = x.first.second;
		int score = x.second;
		sum += score;

		// dbg3(from, current, score)
		if (from == -1) continue;
		cand[current] = score;
		// cand[current] = min({cand[current], score});
		// cand[from] = min({cand[from], score});
	}

	cout << sum << endl;
	repp (i, 1, cand.size()) {
		cout << cand[i] << " ";
		min[cand[i]]--;
	}
	int last = 0;
	for (auto x : min) {
		// dbg2(x.first, x.second)
		if (x.second >= 1) {
			last = x.first;
		}
	}
	cout << last << endl;
	*/
	// cout <<  << endl;

/*
	for (int root = 0; root < N; root++) {
		mp.clear();
		treeDFS(from, root);
		int sum = 0;
		for (auto x : mp) {
			sum += x.second;
			// dbg3(x.first.first, x.first.second, x.second)
		}
		// line()
		dbg(sum)
	}
	*/
}

// treeDFS(親, 現在地, 根から現在地までの距離, 根からの最大の距離, 根から最大の距離となる頂点
void treeDFS2(int from, int current, int dist, int &maxDist, int &maxVertex) {
    // 距離と終点を更新
    if (dist > maxDist) {
        maxDist = dist;
        maxVertex = current;
    }

    for (auto to : G[current]) {
        // 逆流を防ぐ
        if (to == from) continue;
        treeDFS2(current, to, dist + 1, maxDist, maxVertex);
    }
}

pair<int, int> getTreeDiameter() {
    int start = 0, end = 0, maxDist = 0;
    treeDFS2(-1, start, 0, maxDist, end);
    start = end, end = 0, maxDist = 0;
    treeDFS2(-1, start, 0, maxDist, end);
    // printf("start: %d, end: %d, diameter: %d\n", start, end, maxDist);
		return {start, end};
}

signed main() {
	cin >> N;
	rep (i, N-1) {
		int a, b;
		cin >> a >> b;
		a--, b--;
		G[a].push_back(b);
		G[b].push_back(a);
	}
	rep (i, N) {
		cin >> c[i];
	}
	pii h = getTreeDiameter();
	int start = h.first;
	int end = h.second;

	searchTree(start);

	// int a = searchTree(start);
	// int b = searchTree(end);
	// dbg2(a, b)
	// if (a > b) {
	// }

	return 0;
}


Measured memory_bytes: 2432