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 Scala (2.13.1) (judge verdict: Wrong Answer)

import java.io.{BufferedOutputStream, BufferedReader, FileOutputStream, InputStreamReader, PrintWriter}
import java.lang

import scala.annotation.tailrec
import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
import scala.reflect.ClassTag

object Main {
  val DEBUG = false

  lazy val debugOut: PrintWriter = {
    new PrintWriter(new BufferedOutputStream(new FileOutputStream("log.txt", true)))
  }

  def log(message: => String): Unit = {
    if (DEBUG) {
      debugOut.println(message)
    }
  }

  def logf(message: => String): Unit = {
    if (DEBUG) {
      debugOut.println(message)
      debugOut.flush()
    }
  }

  def debug(closure: => Unit): Unit = {
    if (DEBUG) {
      closure
    }
  }

  def get[T: ClassTag](implicit in: BufferedReader, converter: String => T): T = {
    converter(in.readLine)
  }

  def getArray[T: ClassTag](implicit in: BufferedReader, converter: String => T): Array[T] = {
    get[String].split("\\s+").map[T](converter)
  }

  implicit val idConverter: String => String = s => s
  implicit val intConverter: String => Int = s => Integer.parseInt(s)
  implicit val longConverter: String => Long = s => lang.Long.parseLong(s)

  def get[T1, T2](
                   implicit in: BufferedReader,
                   converter1: String => T1,
                   converter2: String => T2
                 ): (T1, T2) = {
    getArray[String] match {
      case Array(v1, v2) => (converter1(v1), converter2(v2))
    }
  }

  def get[T1, T2, T3](
                       implicit in: BufferedReader,
                       converter1: String => T1,
                       converter2: String => T2,
                       converter3: String => T3
                     ): (T1, T2, T3) = {
    getArray[String] match {
      case Array(v1, v2, v3) => (converter1(v1), converter2(v2), converter3(v3))
    }
  }

  def get[T1, T2, T3, T4](
                           implicit in: BufferedReader,
                           converter1: String => T1,
                           converter2: String => T2,
                           converter3: String => T3,
                           converter4: String => T4
                         ): (T1, T2, T3, T4) = {
    getArray[String] match {
      case Array(v1, v2, v3, v4) => (converter1(v1), converter2(v2), converter3(v3), converter4(v4))
    }
  }

  implicit class TimesInt(val n: Int) {
    def times(f: Int => Unit): Unit = {
      for (i <- 0 until n) {
        f(i)
      }
    }
  }

  def primes(n: Long): ArrayBuffer[Long] = {
    val buf = ArrayBuffer.empty[Long]
    val s = Math.sqrt(n).toInt

    var v = n
    for (i <- 2 to s) {
      if (v == 1 || v == 0) {
        return buf
      } else {
        while (v % i == 0) {
          buf.append(i)
          v /= i
        }
      }
    }
    if (v > s) {
      buf.append(v)
    }
    buf
  }

  def divisors(n: Int): ArrayBuffer[Int] = {
    val buf = ArrayBuffer.empty[Int]
    val s = Math.sqrt(n).toInt

    for (i <- 1 to s) {
      if (n % i == 0) {
        buf.append(i)
        if (i != n / i) {
          buf.append(n / i)
        }
      }
    }
    buf
  }

  @tailrec
  def gcd(a: Long, b: Long): Long = {
    val reminder = a % b
    if (reminder == 0) {
      b
    } else {
      gcd(b, reminder)
    }
  }

  @tailrec
  def gcd(a: Int, b: Int): Int = {
    val reminder = a % b
    if (reminder == 0) {
      b
    } else {
      gcd(b, reminder)
    }
  }

  def lcm(a: Long, b: Long): Long = {
    a / gcd(a, b) * b
  }

  def toBitArray(n: Int, width: Int): Array[Boolean] = {
    val buf = ArrayBuffer.fill(width)(false)

    @tailrec
    def inner(n: Int, i: Int): Array[Boolean] = {
      buf(i) = (n & 1) == 0
      if (i == 0) {
        buf.toArray
      } else {
        inner(n / 2, i - 1)
      }
    }

    inner(n, width - 1)
  }

  class ModInt[@specialized(Int) T <: Int](v: Long)(implicit val _m: ValueOf[T]) {
    val m: Long = _m.value
    var value: Long = v % m
    if (value < 0L) {
      value += m
    }

    @inline
    def getValue: Long = value

    override def toString: String = value.toString

    def +(other: ModInt[T]): ModInt[T] = new ModInt[T](value) += other

    def +=(other: ModInt[T]): this.type = {
      value += other.getValue
      if (value >= m) {
        value -= m
      }
      this
    }

    def -(other: ModInt[T]): ModInt[T] = new ModInt(value) -= other

    def -=(other: ModInt[T]): this.type = {
      value -= other.getValue
      if (value < 0) {
        value += m
      }
      this
    }

    def *(other: ModInt[T]): ModInt[T] = new ModInt(value) *= other

    def *=(other: ModInt[T]): this.type = {
      value = value * other.getValue % m
      this
    }

    def /(other: ModInt[T]): ModInt[T] = new ModInt(value) /= other

    def /=(other: ModInt[T]): this.type = {
      var a = other.getValue
      var b = m.toLong
      var u = 1L
      var v = 0L

      while (b > 0L) {
        val t = a / b;
        a -= t * b
        a = a ^ b
        b = a ^ b
        a = a ^ b

        u -= t * v
        u = u ^ v
        v = u ^ v
        u = u ^ v
      }

      value = value * u % m
      if (value < 0) {
        value += m
      }
      this
    }

    def modpow(p: Long): ModInt[T] = {
      @tailrec
      def inner(n: ModInt[T], p: Long, acc: ModInt[T]): ModInt[T] = {
        if (p == 0) {
          acc
        } else if ((p & 1) == 0) {
          inner(n *= n, p >> 1, acc)
        } else {
          inner(n *= n, p >> 1, acc *= n)
        }
      }

      inner(new ModInt[T](value), p, new ModInt[T](1))
    }

    override def equals(other: Any): Boolean = {
      other match {
        case other: ModInt[T] =>
          m == other.m && value == other.value
        case _ => false
      }
    }

    override def hashCode(): Int = {
      (m + value).intValue()
    }
  }

  def main(args: Array[String]): Unit = {
    implicit val in: BufferedReader = new BufferedReader(new InputStreamReader(System.in))
    val out = new PrintWriter(new BufferedOutputStream(System.out))

    log("=== start")
    val n = get[Int]
    val edges = Array.fill(n - 1) {
      get[Int, Int] match {
        case (a, b) => (a - 1, b - 1)
      }
    }
    val cs = getArray[Int].sorted

    val peerSets = Array.fill(n)(mutable.Set.empty[Int])
    for ((a, b) <- edges) {
      peerSets(a).addOne(b)
      peerSets(b).addOne(a)
    }
    val treemap = mutable.TreeMap.empty[Int, mutable.Set[Int]].withDefault(_ => mutable.Set.empty[Int])
    for (i <- peerSets.indices) {
      val peerSet = peerSets(i)
      treemap(peerSet.size) = treemap(peerSet.size).addOne(i)
    }

    val ds = Array.ofDim[Int](n)

    for (c <- cs) {
      val (count, nodeIds) = treemap.head

      logf(s"(count, nodeIds) = (${count}, (${nodeIds.mkString(",")}))")
      val nodeId = nodeIds.head

      ds(nodeId) = c

      nodeIds.remove(nodeId)
      if (nodeIds.isEmpty) {
        treemap.remove(count)
      }
      for (peerNodeId <- peerSets(nodeId)) {
        val size = peerSets(peerNodeId).size
        treemap(size).remove(peerNodeId)
        treemap(size - 1) = treemap(size - 1).addOne(peerNodeId)

        peerSets(peerNodeId).remove(nodeId)
      }
      peerSets(nodeId).empty
    }

    out.println(ds.sum - ds.last)
    out.println(ds.mkString(" "))

    out.flush()
    log("=== end")
    debug {
      debugOut.flush()
    }
  }
}