Problem:
Score : 500 points

Problem Statement

You are given a tree with N vertices 1,2,\ldots,N, and positive integers c_1,c_2,\ldots,c_N.
The i-th edge in the tree (1 \leq i \leq N-1) connects Vertex a_i and Vertex b_i.

We will write a positive integer on each vertex in T and calculate our score as follows:

On each edge, write the smaller of the integers written on the two endpoints.

Let our score be the sum of the integers written on all the edges.

Find the maximum possible score when we write each of c_1,c_2,\ldots,c_N on one vertex in T, and show one way to achieve it. If an integer occurs multiple times in c_1,c_2,\ldots,c_N, we must use it that number of times.

Constraints

1 \leq N \leq 10000

1 \leq a_i,b_i \leq N

1 \leq c_i \leq 10^5

The given graph is a tree.

Input

Input is given from Standard Input in the following format:

N
a_1 b_1
:
a_{N-1} b_{N-1}
c_1 \ldots c_N

Output

Use the following format:

M
d_1 \ldots d_N

where M is the maximum possible score, and d_i is the integer to write on Vertex i.
d_1,d_2,\ldots,d_N must be a permutation of c_1,c_2,\ldots,c_N.
If there are multiple ways to achieve the maximum score, any of them will be accepted.

Sample Input 1

5
1 2
2 3
3 4
4 5
1 2 3 4 5

Sample Output 1

10
1 2 3 4 5

If we write 1,2,3,4,5 on Vertex 1,2,3,4,5, respectively, the integers written on the four edges will be 1,2,3,4, for the score of 10. This is the maximum possible score.

Sample Input 2

5
1 2
1 3
1 4
1 5
3141 59 26 53 59

Sample Output 2

197
59 26 3141 59 53

c_1,c_2,\ldots,c_N may not be pairwise distinct.

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#ifdef __GNUC__ 
#include <bits/stdc++.h>
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
auto & inputdatastream = std::cin;
#define popcnt __builtin_popcountll
#else
std::ifstream inputdatastream;
unsigned int popcnt(unsigned long long a) {
	a = (a >> 1) & 0x5555'5555'5555'5555ull + 0x5555'5555'5555'5555ull & a;
	a = (a >> 2) & 0x3333'3333'3333'3333ull + 0x3333'3333'3333'3333ull & a;
	a = (a >> 4) & 0x0f0f'0f0f'0f0f'0f0full + 0x0f0f'0f0f'0f0f'0f0full & a;
	a = (a >> 8) + a;
	a = (a >> 16) & 0x0000'ffff'0000'ffffull + 0x0000'ffff'0000'ffffull & a;
	a = (a >> 32) & 0x0000'0000'ffff'ffffull + 0x0000'0000'ffff'ffffull & a;
	return static_cast<unsigned int>(a);
}
#endif
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/dynamic_bitset.hpp>
#include <boost/preprocessor.hpp>
#include <boost/mpl/int.hpp>
#include <boost/range.hpp>
#include <boost/icl/map.hpp>
#include <immintrin.h>
#include <iterator>
//#include <boost/numeric/ublas/blas.hpp>
//#include <boost/numeric/ublas/matrix.hpp>
//#include <boost/numeric/ublas/io.hpp>
//#include <boost/numeric/ublas/matrix_proxy.hpp>
using namespace std;
namespace renge = boost::range;

#define ALL(v) std::begin(v),std::end(v)


#define RALL(v) std::rbegin(v),std::rend(v)
using u6 = std::uint64_t;
using s6 = std::int64_t;
using u3 = std::uint32_t;
using u1 = std::uint16_t;
using s3 = std::int32_t;

constexpr u6 moduloNo = 1'000'000'000 + 7; //' 1e9 + 7
#define DEFVALUE1(r,type,name) type name;
#define DEFINIT0(r,type,name) in >> name;
#define DEFINIT1(r,size,name) name.resize(size);
#define DEFOSTREAM_FORDEBUG(r,type,name) out << name << " ";
#define DEFINITER template <typename T, typename In> void init(const T &, In &) {}
#define DEF_TYPEEXTSELECTOR(fnext,tpl)BOOST_PP_IF(BOOST_PP_TUPLE_ELEM(0, fnext)  ,BOOST_PP_TUPLE_ELEM(2, fnext),BOOST_PP_TUPLE_ELEM(0, tpl) )
#define DEFVALUEIMPL(r,fnext,tpl) BOOST_PP_LIST_FOR_EACH(BOOST_PP_TUPLE_ELEM(1,fnext),DEF_TYPEEXTSELECTOR(fnext,tpl), BOOST_PP_TUPLE_TO_LIST(BOOST_PP_TUPLE_POP_FRONT(tpl)))
#define DEFVALUES(expr) DEFIMPL(expr,0,DEFINIT0,0,_)
#define DEFIMPL(expr,deftypeindex,initcode,c,ext)																									\
			BOOST_PP_SEQ_FOR_EACH(DEFVALUEIMPL,(0,DEFVALUE1,_),BOOST_PP_VARIADIC_SEQ_TO_SEQ(expr))													\
			template <typename In> decltype(auto) init(boost::mpl::int_<deftypeindex> ,In & in){													\
				BOOST_PP_SEQ_FOR_EACH(DEFVALUEIMPL,(c,initcode,ext),BOOST_PP_VARIADIC_SEQ_TO_SEQ(expr));return in;}									\
			template <typename Out> decltype(auto) init(boost::mpl::int_<-deftypeindex-1>, Out & out) {												\
					BOOST_PP_SEQ_FOR_EACH(DEFVALUEIMPL, (c, DEFOSTREAM_FORDEBUG, ext), BOOST_PP_VARIADIC_SEQ_TO_SEQ(expr)); return out;}
#define DEFVECS(size,expr)  DEFIMPL(expr,1,DEFINIT1,1,size)
#define DEFSTRUCT(name,...) struct name{DEFINITER;__VA_ARGS__ ;friend std::istream & operator>>(std::istream & in,name & target){				\
		target.init(boost::mpl::int_<0> (),in);target.init(boost::mpl::int_<1>() ,in);return in;}												\
	friend std::ostream & operator<<(std::ostream & out, name & target) {																		\
			target.init(boost::mpl::int_<-1>(), out); return out;} }

template <typename T>
void initcalc(T & calc) {
	ios::sync_with_stdio(false); cin.tie(0);
#ifndef __GNUC__ 
	inputdatastream.open("inputdata.txt");
#endif
	calc.init(boost::mpl::int_<0>(), inputdatastream);
	calc.init(boost::mpl::int_<1>(), inputdatastream);
}
template <typename T>
auto runcalc(T & c) ->std::enable_if_t<std::is_void<decltype(c.calc())>::value > {
	c.calc();
}
template <typename T>
auto runcalc(T & c) ->std::enable_if_t<!std::is_void<decltype(c.calc())>::value > {
	std::cout << c.calc() << std::endl;
}
template <typename T>
struct invecT {
	decltype(auto) begin()const {
		return std::istream_iterator<T>(inputdatastream);
	}
	decltype(auto) end()const {
		return std::istream_iterator<T>();
	}
};
template <typename T>invecT<T> invec;
//-------------------------------------------------------------------------------

namespace nightly {

	template <typename T, bool isZeronodeCount = true>
	struct unionfind {
		std::vector<T> v;
		T count;
		void resize(std::size_t n) {
			assert(v.size() == 0); v.resize(n + 1);
			if (isZeronodeCount)count = v.size() - 1;
			else count = 0;
		}
		template <bool ismerge>
		bool find(T l, T r) {//可変長引数とかも選択肢？
			auto ll = getroot(l);
			auto rr = getroot(r);
			auto update = [this](const auto & updateindex, T minval) {
				for (auto i : updateindex)v[i] = minval;
			};
			if (ismerge) {
				std::pair<T, T> t = std::minmax(ll.first, rr.first);
				if (ll.first != rr.first) {
					--count;
					v[t.second] = t.first;
				}
				update(ll.second, t.first);
				update(rr.second, t.first);
			}
			else {
				update(ll.second, ll.first);
				update(rr.second, rr.first);
			}
			return ll.first == rr.first;
		}
	private:
		std::pair<T, std::vector<T> > getroot(T node) {
			std::pair<T, std::vector<T> > result;
			if (!v[node])v[node] = node;
			while (v[node] != node) {
				result.second.push_back(node);
				node = v[node];
			}
			result.first = node;
			return result;
		}
	};
	template <typename T = s6>
	struct midianset {
		multiset<T> s;
		typename multiset<T>::iterator mid;
		s6 sums[2] = {};
		auto size()const { return s.size(); }
		void ajust(unsigned cond, T val) {
			static_assert((5 > 3) == 1, "***true!=1***");
			sums[!cond] += val;
			if ((s.size() & 1u) != cond) {
				sums[cond] += *mid;
				cond ? --mid : ++mid;
				sums[!cond] -= *mid;
			}
		}
		void insert(T val) {
			if (s.size() == 0) mid = s.insert(val);
			else {
				s.insert(val);
				ajust(val < *mid, val);
			}
		}
		auto sum() const noexcept {
			return tuple<T, T, T>(sums[0], *mid, sums[1]);
		}
	};


}using namespace nightly;
/*******************************************************************************/
//constexpr u6 shiftsize = 10+5;
//constexpr u6 bufsize = 1 << shiftsize;

DEFSTRUCT(datatype, DEFVALUES(///////////////////////////////////////////////////////
		(string , a)
	)///////////////////////////////////////////////////////
);


namespace mp = boost::multiprecision;
//using mp6=mp::number<mp::cpp_int_backend<64, 64, mp::unsigned_magnitude, mp::unchecked>>;
//typedef decltype (mulmm<250>::mul(t1, t2))) typea;
using vertext = vector<pair<set<u3>,u3>>;

struct Calc {
	DEFINITER;
	DEFVALUES(//////////////////////////////////////////////////
		(u3, N)
	);///////////////////////////////////////////////////////

	auto  calc() {
		vertext vectex(N);
		auto initvectex = [&](auto i, auto j) {
			get<0>(vectex[i-1]).insert(j);
		};
		for (int i = 0; i < N-1; ++i) {
			u3 a, b;
			inputdatastream >> a >> b;
			initvectex(a, b);
			initvectex(b, a);
		}
		vector<u3> vectexindex(N);
		for (int i = 0; i < N; ++i) {
			vectexindex[i] = i+1;
		}
		vector<u3> cvec;
		cvec.reserve(N);
		for (auto c : invec<u3>)cvec.push_back(c);
		sort(ALL(cvec));
		sort(ALL(vectexindex), [&vectex](const auto & lhs, const auto & rhs) {return get<0>(vectex[lhs-1]).size() < get<0>(vectex[rhs-1]).size(); });
		auto vitebase = vectexindex.begin();
		auto vite= vitebase;
		u3 currentindex = 0;
		u3 count = 0;
		for (auto c : cvec) {
			if (currentindex == 0 ||vectex[currentindex - 1].second !=0 || vectex[currentindex - 1].first.size() > 1) {
				while (vectex[*vite-1].second != 0)++vite;
				currentindex = *vite;
				++vite;
			}
			//cout << c << endl;
			vectex[currentindex-1].second = c;
			++count;
			if (count == N)break;
			auto prev = currentindex;
			currentindex = *vectex[currentindex - 1].first.begin();
			vectex[currentindex - 1].first.erase(prev);
		}
		cout << accumulate(ALL(cvec),0) - cvec.back() << endl;
		bool st = false;
		for (const auto & t : vectex) {
			if (st)cout << " ";
			st = true;
			cout << t.second;
		}
		cout << endl;
		return ;
	}
	/*******************************************************************************/
};

int main() {
	static Calc calc;
	initcalc(calc); runcalc(calc);
}