object Main {

  def main(args: Array[String]): Unit = {
    import scala.collection.mutable.ArrayBuffer
    val sc = new java.util.Scanner(System.in)

    val N = sc.nextShort()
    val E = Array.fill(N)(ArrayBuffer[Short]())
    val Dim = new Array[Int](N)
    val visited = new Array[Boolean](N)
    (0 until N - 1) foreach { _ =>
      val _a, _b = sc.nextShort()
      val a: Short = (_a - 1).toShort
      val b: Short = (_b - 1).toShort
      E(a).append(b)
      E(b).append(a)
      Dim(a) += 1
      Dim(b) += 1
    }
    var C = Array.fill(N)(sc.nextInt()).sorted(Ordering.Int.reverse).toList
    val D = new Array[Int](N) // 最終結果
    // 入次数が小さい順に訪れて行き,

    var M = 0
    val (_, root) = Dim.zipWithIndex.minBy(_._1) // 入次数がもっとも小さいものをルートとする
    def bfs(u: Int): Unit =
      E(u) foreach { v =>
        if (!visited(v)) {
          visited(v) = true
          D(v) = C.head // 一番価値が高いものを取り出してuに入れる
          C = C.tail // 残りをCに入れて更新する
          M += D(v) // 新しく追加した辺の価値は子のほうがちいさいので蓄積
          bfs(v) // さらにその子孫を探索
        }
      }

    visited(root) = true
    D(root) = C.head
    C = C.tail
    bfs(root)

    println(M)
    println(D.mkString(" "))
  }

}