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

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pullull;
typedef pair<ll, int> plli;
typedef pair<int, pii> pipii;
typedef vector<vector<int> > mati;
typedef vector<vector<double> > matd;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;
typedef vector<vector<vector<ll>>> vvvll;
typedef vector<bool> vb;
typedef vector<vector<bool>> vvb;
typedef vector<vector<vector<bool>>> vvvb;
typedef vector<pll> vpll;

#define FOR(i,x,y) for(ll i=(ll)x; i<(ll)y; ++i)
#define REP(i,y) FOR(i, 0, y)
#define RFOR(i,x,y) for(ll i=(ll)x; i>=(ll)y; --i)
#define RREP(i,x) RFOR(i, x, 0)
#define ALL(a) a.begin(), a.end()
#define pb push_back

inline void IN(void){
  return;
}

template <typename First, typename... Rest>
void IN(First& first, Rest&... rest){
  cin >> first;
  IN(rest...);
  return;
}

inline void OUT(void){
  cout << "\n";
  return;
}

template <typename First, typename... Rest>
void OUT(First first, Rest... rest){
  cout << first << " ";
  OUT(rest...);
  return;
}

template <typename T>
void vec_print(vector<T> VEC){
  REP(i, VEC.size()){
    cout << VEC[i] << " ";
  }
  cout << "\n";
};

template <typename T>
void mat_print(vector<vector<T> > MAT){
  REP(i, MAT.size()){
    REP(j, MAT[i].size()){
      cout << MAT[i][j] << " ";
    }
    cout << "\n";
  }
};

template <typename CLASS1, typename CLASS2>
class HOGE{
  public:
    CLASS1 key;
    CLASS2 value;
    HOGE(void){
      return;
    };
    HOGE(CLASS1 key, CLASS2 value){
      this->key = key;
      this->value = value;
    };
    ~HOGE(void){
      return;
    };

    void print(void){
      cout << "key : " << key << ", value : " << value << "\n";
      return;
    };
    
    bool operator==(const HOGE &obj){
      return (this->value == obj.value);
    };
    bool operator<(const HOGE &obj){
      return (this->value < obj.value);
    };
    bool operator>(const HOGE &obj){
      return (this->value > obj.value);
    };
};

template <typename CLASS1, typename CLASS2>
bool operator==(const HOGE<CLASS1, CLASS2> &hoge1, const HOGE<CLASS1, CLASS2> &hoge2){
  return hoge1.value == hoge2.value;
};

template <typename CLASS1, typename CLASS2>
bool operator<(const HOGE<CLASS1, CLASS2> &hoge1, const HOGE<CLASS1, CLASS2> &hoge2){
  return hoge1.value < hoge2.value;
};

template <typename CLASS1, typename CLASS2>
bool operator>(const HOGE<CLASS1, CLASS2> &hoge1, const HOGE<CLASS1, CLASS2> &hoge2){
  return hoge1.value > hoge2.value;
};

constexpr int INF = (1<<30);
constexpr ll INFLL = 1LL<<62;
constexpr long double EPS = 1e-12;
constexpr ll MOD = (ll)((1E+9)+7);

class Tree{
  private:
    // V nodes and V-1 edges
    ll V;
    vvll Path;
    ll diameter;
    vll diameter_pair;
    ll radius;
    vll radius_pair;
    ll num_of_center_of_gravities;
    vll center_of_gravities;
  public:
    Tree(ll V_){
      V = V_;
      Path.resize(V);
      diameter = -1;
      radius = -1;
      num_of_center_of_gravities = -1;
      diameter_pair.resize(0);
      radius_pair.resize(0);
      center_of_gravities.resize(0);
      return;
    };

    ~Tree(void){
      return;
    };

    void add(ll x, ll y){
      Path[x].push_back(y);
      Path[y].push_back(x);
      diameter = -1;
      radius = -1;
      num_of_center_of_gravities = -1;
      return;
    };

    ll get_diameter(void){
      if(this->diameter>0) return this->diameter;
      vll flag(V, true);
      vll front_points;
      front_points.push_back(0);
      flag[0] = false;
      while(true){
        vll front_points_copy = front_points;
        front_points.clear();
        for(auto x : front_points_copy){
          for(auto y : Path[x]){
            if(!flag[y]) continue;
            front_points.push_back(y);
            flag[y] = false;
          }
        }
        if(front_points.size()==0){
          front_points = front_points_copy;
          break;
        }
      }

      flag.assign(V, true);
      ll u = front_points[0];
      front_points.clear();
      front_points.push_back(u);
      flag[u] = false;
      ll d = 0;
      while(true){
        vll front_points_copy = front_points;
        front_points.clear();
        for(auto x : front_points_copy){
          for(auto y : Path[x]){
            if(!flag[y]) continue;
            front_points.push_back(y);
            flag[y] = false;
          }
        }
        if(front_points.size()==0){
          front_points = front_points_copy;
          break;
        }
        d++;
      }
      ll v = front_points[0];

      this->diameter = d;
      this->diameter_pair.push_back(u);
      this->diameter_pair.push_back(v);

      return d;
    };
    
    vll get_diameter_pair(void){
      if(this->diameter<=0){
        get_diameter();
      }
      return this->diameter_pair;
    };

    ll get_radius(void){
      if(radius>0) return radius;

      vll leaves;
      vll connects(V);
      for(ll i=0; i<V; ++i){
        connects[i]=Path[i].size();
        if(connects[i]==1) leaves.push_back(i);
      }

      ll r=0;
      while(true){
        vll leaves_copy = leaves;
        leaves.clear();
        for(auto x : leaves_copy){
          connects[x] = 0;
          for(auto y : Path[x]){
            connects[y]--;
            if(connects[y]==1) leaves.push_back(y);
          }
        }
        if(leaves.size()==0){
          leaves = leaves_copy;
          if(leaves_copy.size()==2){
            r++;
          }
          break;
        }

        r++;
      }

      this->radius = r;
      this->radius_pair = leaves;

      return radius;
    };

    vll get_radius_pair(void){
      if(this->radius<=0){
        get_radius();
      }
      return this->radius_pair;
    };

    ll getsize(ll x, vll& flag){
      flag[x] = false;
      ll ans = 1;
      for(auto y : Path[x]){
        if(!flag[y]) continue;
        ans += getsize(y, flag);
      }
      return ans;
    };

    ll get_num_of_center_of_gravities(void){
      if(this->num_of_center_of_gravities>0) return this->num_of_center_of_gravities;
      ll v=0;
      ll max_size = V;
      ll counter = 0;
      vll c_of_g;
      while(true){
        ll max_size = -1;
        ll next_v = -1;
        vll flag(V, true);
        flag[v] = false;
        for(auto y : Path[v]){
          ll y_size = getsize(y, flag);
          if(max_size < y_size){
            max_size = y_size;
            next_v = y;
          }
        }
        if(max_size<=V/2){
          counter++;
          c_of_g.push_back(v);
          if(counter>=2) break;
        }else if(counter>0){
          break;
        }
        v = next_v;
      }

      this->num_of_center_of_gravities = c_of_g.size();
      this->center_of_gravities = c_of_g;
      return this->num_of_center_of_gravities;
    };

    vll get_center_of_gravities(void){
      if(this->num_of_center_of_gravities<=0) get_num_of_center_of_gravities();
      return this->center_of_gravities;
    }
};

int main(){
  cin.tie(0); // cut the cin and cout (default, std::flush is performed after std::cin)
  ios::sync_with_stdio(false); // cut the iostream and stdio (DON'T endl; BUT "\n";)

  ll N;
  IN(N);
  vvll Path(N);
  Tree tree(N);
  REP(i,N-1){
    ll a, b;
    IN(a,b);
    a--;
    b--;
    Path[a].pb(b);
    Path[b].pb(a);
    tree.add(a,b);
  }
  vll c(N);
  REP(i,N){
    IN(c[i]);
  }
  sort(ALL(c));
  ll ans = 0;
  REP(i,N-1) ans += c[i];
  reverse(ALL(c));
  ll count = 0;

  vll radius_pair = tree.get_radius_pair();

  queue<ll> que;
  vll d(N, -1);
  que.push(radius_pair[0]);
  while(!que.empty()){
    ll pos = que.front(); que.pop();

    d[pos] = c[count];
    count++;

    REP(i, Path[pos].size()){
      if(d[Path[pos][i]]>=0) continue;
      que.push(Path[pos][i]);
    }
  }

  printf("%d\n", ans);
  REP(i, N){
    printf("%d ", d[i]);
  }
  printf("\n");

  return 0;
}

Measured memory_bytes: 1920