#include<bits/stdc++.h>
using namespace std;
using vi = vector<int>;
using pi = pair<int,int>;
typedef long long ll;
#define debug(x) cout << #x << " = " << x << "\n";
#define vdebug(a) cout << #a << " = "; for(auto x: a) cout << x << " "; cout << "\n";
const int MOD = 1e9 + 7;
const int INF = 1e9;
template<ll mod>
struct modnum {
	static constexpr bool is_big_mod = mod > numeric_limits<int>::max();
	using S = conditional_t<is_big_mod, ll, int>;
	using L = conditional_t<is_big_mod, __int128, ll>;
	S x;
	modnum() : x(0) {}
	modnum(ll _x) {
		_x %= static_cast<ll>(mod);
		if (_x < 0) { _x += mod; }
		x = _x;
	}
	modnum pow(ll n) const {
		modnum res = 1;
		modnum cur = *this;
		while (n > 0) {
			if (n & 1) res *= cur;
			cur *= cur;
						n /= 2;
		}
		return res;
	}
	modnum inv() const { return (*this).pow(mod-2); }
	modnum& operator+=(const modnum& a){
		x += a.x;
		if (x >= mod) x -= mod;
		return *this;
	}
	modnum& operator-=(const modnum& a){
		if (x < a.x) x += mod;
		x -= a.x;
		return *this;
	}
	modnum& operator*=(const modnum& a){
		x = static_cast<L>(x) * a.x % mod;
		return *this;
	}
	modnum& operator/=(const modnum& a){ return *this *= a.inv(); }
	friend modnum operator+(const modnum& a, const modnum& b){ return modnum(a) += b; }
	friend modnum operator-(const modnum& a, const modnum& b){ return modnum(a) -= b; }
	friend modnum operator*(const modnum& a, const modnum& b){ return modnum(a) *= b; }
	friend modnum operator/(const modnum& a, const modnum& b){ return modnum(a) /= b; }
	friend bool operator==(const modnum& a, const modnum& b){ return a.x == b.x; }
	friend bool operator!=(const modnum& a, const modnum& b){ return a.x != b.x; }
	friend bool operator<(const modnum& a, const modnum& b){ return a.x < b.x; }
	friend ostream& operator<<(ostream& os, const modnum& a){ os << a.x; return os; }
	friend istream& operator>>(istream& is, modnum& a) { ll x; is >> x; a = modnum(x); return is; }
};
using mint = modnum<MOD>;
template <class T> class SumSegmentTree {
  private:
	const T DEFAULT = 0;
	vector<T> segtree;
	int len;
  public:
	SumSegmentTree(int len) : len(len), segtree(len * 2, DEFAULT) {}
	void set(int ind, T val) {
		ind += len;
		segtree[ind] = val;
		for (; ind > 1; ind /= 2) {
			segtree[ind / 2] = segtree[ind] + segtree[ind ^ 1];
		}
	}
	T range_sum(int start, int end) {
		T sum = DEFAULT;
		for (start += len, end += len; start < end; start /= 2, end /= 2) {
			if (start % 2 == 1) { sum += segtree[start++]; }
			if (end % 2 == 1) { sum += segtree[--end]; }
		}
		return sum;
	}
};
/*
const int N = 250005;
struct BIT {
  ll b[N], n;
  void init(int _n) {
	n = _n ;
	for(int i = 0 ; i <= n ; ++i) b[i] = 0;
  }
  inline int lowbit(int x) { return x & (-x); }
  void update(int x, ll v) {
	for(int i = x ; i <= n ; i += lowbit(i)) b[i] += v;
  }
  ll query(int x) {
	ll ans = 0;
	for(int i = x ; i > 0 ; i -= lowbit(i)) ans += b[i];
	return ans;
  }
} bit[2]; */
int gcd(int a, int b, int& x, int& y) { // x*a + y*b = a1
    x = 1, y = 0;
    int x1 = 0, y1 = 1, a1 = a, b1 = b;
    while (b1) {
        int q = a1 / b1;
        tie(x, x1) = make_tuple(x1, x - q * x1);
        tie(y, y1) = make_tuple(y1, y - q * y1);
        tie(a1, b1) = make_tuple(b1, a1 - q * b1);
    }
    return a1;
}
int inv_ecd(int a, int m) {
	int x, y;
	int g = gcd(a, m, x, y);
	if(g != 1) return -1;
	x = (x + m) % m;
	return x;
}
const int N2 = 1e5;
vi adjL[N2], sz, tin, T, ans2;
int cnt, N, val2;
int dfs(int pos, int prev, vi &ans) {
    int cnt = 0;
    for(int adj: adjL[pos]) {
        if(adj == prev) continue;
        cnt += dfs(adj, pos, ans);
    }
    if(pos && ans[pos] == pos) {
        ans[pos] = ans[prev];
        ans[prev] = pos;
        cnt += 2;
    } else if(!pos && ans[pos] == pos){
        ans[pos] = ans[adjL[pos][0]];
        ans[adjL[pos][0]] = 0;
        cnt += 2;
    }
    return cnt;
}
void get_sz(int pos, int prev) {
    sz[pos] = 1;
    for(int adj: adjL[pos]) {
        if(adj == prev) continue;
        get_sz(adj, pos);
        sz[pos] += sz[adj];
    }
    val2 += 2 * min(sz[pos], N-sz[pos]);
}
int find_centroid(int pos, int prev, int n) {
    for(int adj: adjL[pos]) {
        if(adj != prev && 2*sz[adj] > n) return find_centroid(adj, pos, n);
    }
    return pos;
}
void dfs2(int pos, int prev=-1) {
    tin[pos] = cnt;
    T[cnt++] = pos;
    for(int adj: adjL[pos]) {
        if(adj == prev) continue;
        dfs2(adj, pos);
    }
}
void calc(int v, int n) {
    get_sz(v, v);
    cnt = 0;
    dfs2(find_centroid(v, v, n));
    for(int i=0; i<n; ++i) {
        int x = (tin[i] + n/2) % n;
        ans2[T[x]] = i;
    }
}
void solve() {
    int n;
    cin >> n;
    N = n;
    vi ans(n);
    ans2.resize(n);
    for(int i=0; i<n-1; ++i) {
        ans[i] = ans2[i] = i;
        int x, y;
        cin >> x >> y;
        --x, --y;
        adjL[x].push_back(y);
        adjL[y].push_back(x);
    }
    ans[n-1] = ans2[n-1] = n-1;
    sz.resize(n);
    tin.resize(n);
    T.resize(n);
    int val = dfs(0, 0, ans);
    calc(0, n);
    cout << val << " " << val2 << endl;
    for(int x: ans) cout << x+1 << " ";
    cout << endl;
    for(int x: ans2) cout << x+1 << " ";
    cout << endl;
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	//freopen("strange_file.txt", "r", stdin);
	//freopen("strange_file3.txt", "w", stdout);
	int tc = 1;
	while (tc--) solve();
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |