#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
vector<pair<int, int>> g[N];
long long d[N], b[N];
int s[N], e[N], t, sz[N];
set<int> ts[N];
void dfs(int x, int par, int y, long long a) {
  s[x] = t++;
  d[x] = a;
  b[x] = par;
  sz[x] = 1;
  for (auto v : g[x])
    if (v.first != y) {
      dfs(v.first, par, x, a + v.second);
      sz[x] += sz[v.first];
    }
  e[x] = t;
}
bool tk[N];
int fat[N];
int szt[N];
int calcsz(int x, int f) {
  szt[x] = 1;
  for (auto y : g[x])
    if (y.first != f && !tk[y.first]) szt[x] += calcsz(y.first, x);
  return szt[x];
}
int cdfs(int x = 0, int f = -1, int sz = -1) {
  if (sz < 0) sz = calcsz(x, -1);
  for (auto y : g[x])
    if (!tk[y.first] && szt[y.first] * 2 >= sz) {
      szt[x] = 0;
      return cdfs(y.first, f, sz);
    }
  return x;
}
struct STree {
  vector<int> st;
  int n;
  STree(int n) : st(4 * n + 5, 1e6), n(n) {}
  void init(int k, int s, int e, int *a) {
    if (s + 1 == e) {
      st[k] = a[s];
      return;
    }
    int m = (s + e) / 2;
    init(2 * k, s, m, a);
    init(2 * k + 1, m, e, a);
    st[k] = min(st[2 * k], st[2 * k + 1]);
  }
  void upd(int k, int s, int e, int p, int v) {
    if (s + 1 == e) {
      st[k] = v;
      return;
    }
    int m = (s + e) / 2;
    if (p < m)
      upd(2 * k, s, m, p, v);
    else
      upd(2 * k + 1, m, e, p, v);
    st[k] = min(st[2 * k], st[2 * k + 1]);
  }
  int query(int k, int s, int e, int a, int b) {
    if (s >= b || e <= a) return 1e6;
    if (s >= a && e <= b) return st[k];
    int m = (s + e) / 2;
    return min(query(2 * k, s, m, a, b), query(2 * k + 1, m, e, a, b));
  }
  void init(int *a) { init(1, 0, n, a); }
  void upd(int p, int v) { upd(1, 0, n, p, v); }
  int query(int a, int b) { return query(1, 0, n, a, b); }
};
int doQuery(int u, int k, STree &rmq) {
  if (!k) return min(rmq.query(0, s[u]), rmq.query(e[u], N));
  return rmq.query(s[u], e[u]);
}
int main() {
  int n;
  cin >> n;
  for (int i = 1; i < n; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    u--, v--;
    g[u].push_back({v, w});
    g[v].push_back({u, w});
  }
  int centroid = cdfs();
  long long res = 0;
  s[centroid] = t++;
  b[centroid] = centroid;
  for (auto v : g[centroid]) {
    dfs(v.first, v.first, centroid, v.second);
    sz[v.first] *= 2;
    ts[sz[v.first]].insert(v.first);
  }
  e[centroid] = t;
  for (int i = 0; i < n; i++) res += d[i];
  cout << 2 * res << endl;
  STree rmq(n);
  for (int i = 0; i < n; i++) {
    rmq.upd(s[i], i);
  }
  vector<int> p(n);
  for (int i = 0; i < n; i++) {
    vector<int> must;
    for (auto x : ts[n - i]) must.push_back(x);
    if (((int)must.size()) == 2) {
      int x = must[b[i] == must[0]];
      p[i] = doQuery(must[b[i] == must[0]], 1, rmq);
    } else if (((int)must.size()) == 1) {
      if (b[i] == must[0])
        p[i] = doQuery(b[i], 0, rmq);
      else
        p[i] = doQuery(must[0], 1, rmq);
    } else {
      if (i == centroid)
        p[i] = rmq.st[1];
      else
        p[i] = doQuery(b[i], 0, rmq);
    }
    rmq.upd(s[p[i]], 1e6);
    int u = b[i], v = b[p[i]];
    if (centroid != u) ts[sz[u]].erase(u), ts[--sz[u]].insert(u);
    if (centroid != v) ts[sz[v]].erase(v), ts[--sz[v]].insert(v);
  }
  for (int i = 0; i < n; i++) cout << p[i] + 1 << " ";
  cout << endl;
  return 0;
}
