#include <bits/stdc++.h>
using namespace std;
#define db(x) cerr << #x << "=" << x << endl
#define db2(x, y) cerr << #x << "=" << x << "," << #y << "=" << y << endl
#define db3(x, y, z) cerr << #x << "=" << x << "," << #y << "=" << y << "," << #z << "=" << z << endl
#define dbv(v) cerr << #v << "="; for (auto _x : v) cerr << _x << ", "; cerr << endl
#define dba(a, n) cerr << #a << "="; for (int _i = 0; _i < (n); ++_i) cerr << a[_i] << ", "; cerr << endl
typedef long long ll;
typedef long double ld;
vector<int> adj[200005];
namespace nstree {
int lcaIter, dfsIter, logn;
vector<int> depth, lcaFir, lcaLas, lcaSeq;
vector<vector<int>> lcaTable;
vector<vector<int>> anc;
vector<int> parent, pre, endpre, siz;
vector<vector<pair<int, int>>> chPost;
void dfs(int x, int p = -1) {
	parent[x] = p;
	lcaFir[x] = lcaIter;
	lcaSeq[lcaIter++] = x;
	siz[x] = 1;
	pre[x] = dfsIter++;
	for (auto y : adj[x]) {
		if (y == p) continue;
		depth[y] = depth[x] + 1;
		dfs(y, x);
		siz[x] += siz[y];
		lcaSeq[lcaIter++] = x;
		chPost[x].emplace_back(lcaLas[y], y);
	}
	lcaLas[x] = lcaIter - 1;
	endpre[x] = dfsIter; // This is the last vertex in the subtree of x
}
int getLca(int a, int b) {
	a = lcaFir[a];
	b = lcaFir[b];
	if (a > b) swap(a, b);
	int p = 31 - __builtin_clz(b - a + 1);
	int x = lcaTable[p][a];
	int y = lcaTable[p][b - (1 << p) + 1];
	return depth[x] < depth[y] ? x : y;
}
void init(int n) {
	depth.resize(n + 1);
	lcaFir.resize(n + 1);
	lcaLas.resize(n + 1);
	parent.resize(n + 1);
	pre.resize(n + 1);
	endpre.resize(n + 1);
	siz.resize(n + 1);
	chPost.clear();
	chPost.resize(n + 1);
	lcaSeq.resize(2 * n - 1);
	lcaIter = dfsIter = 0;
	logn = 31 - __builtin_clz(n);
	dfs(1);
	assert(lcaIter == 2 * n - 1);
	int lcaLog = 32 - __builtin_clz(2 * n - 1);
	lcaTable.resize(lcaLog);
	lcaTable[0] = lcaSeq;
	for (int p = 1; p < lcaLog; ++p) {
		lcaTable[p].resize(lcaIter - (1 << p) + 1);
		for (int i = 0; i <= lcaIter - (1 << p); ++i) {
			int x = lcaTable[p - 1][i];
			int y = lcaTable[p - 1][i + (1 << (p - 1))];
			lcaTable[p][i] = depth[x] < depth[y] ? x : y;
		}
	}
//	anc.resize(logn + 1, vector<int>(n + 1));
//	anc[0] = parent;
//	// Below is for power jumping
//	for (int p = 1; p <= logn; ++p)
//		for (int i = 1; i <= n; ++i) {
//			int a = anc[p - 1][i];
//			if (a != -1) {
//				anc[p][i] = anc[p - 1][a];
//				if (anc[p][i] != -1) {
//					// do something with ancestor here
//				}
//			}
//		}
}
bool isAnc(int a, int b) {
	return lcaFir[a] <= lcaFir[b] && lcaLas[a] >= lcaLas[b];
}
int getChildTowards(int a, int sub) {
	auto it = lower_bound(chPost[a].begin(), chPost[a].end(), make_pair(lcaLas[sub], -1));
	return it->second;
}
};
using namespace nstree;
int main() {
	int n;
	scanf("%d", &n);
	for (int i = 1; i < n; ++i) {
		int a, b;
		scanf("%d%d", &a, &b);
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	init(n);
	vector<int> c(n), id(n), ans(n + 1);
	for (int i = 0; i < n; ++i) scanf("%d", &c[i]);
	sort(c.begin(), c.end());
	iota(id.begin(), id.end(), 1);
	sort(id.begin(), id.end(), [&](int x, int y) { return siz[x] < siz[y]; });
	ll val = 0;
	for (int i = 0; i < n; ++i) {
		ans[id[i]] = c[i];
		if (i + 1 < n) val += c[i];
	}
	printf("%lld\n", val);
	for (int i = 1; i <= n; ++i) printf("%d ", ans[i]);
}


Measured memory_bytes: 8320