根节点到每个节点经过的轻链总数不超过log(n),因此可以把轻链放在20上,把重链放在1e6上,同时用dfs序将节点分布开,就可以满足要求了,注意一下dfs的顺序,先遍历轻链再遍历重链,这样可以保证不交叉

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 10;
int mem, head[maxn];
struct Edge { int to, next; }edges[maxn<<1];
void addedge(int from, int to) {
edges[mem].to = to; edges[mem].next = head[from]; head[from] = mem++;
}
int sz[maxn], son[maxn];
int x[maxn], y[maxn], cnt;
void init() {
mem = 0;
memset(head, -1, sizeof(head));
cnt = 0;
}
void dfs1(int f, int u) {
sz[u] = 1;
son[u] = -1;
for (int i = head[u]; ~i; i = edges[i].next) {
int v = edges[i].to;
if (v == f) continue;
dfs1(u, v);
sz[u] += sz[v];
if (son[u] == -1 || sz[v] > sz[son[u]]) son[u] = v;
}
}
void dfs2(int f, int u, int d) {
x[u] = ++cnt;
y[u] = d;
if (son[u] == -1) return;
for (int i = head[u]; ~i; i = edges[i].next) {
int v = edges[i].to;
if (v == f || v == son[u]) continue;
dfs2(u, v, d+1);
}
dfs2(u, son[u], d);
}
int main() {
int n;
scanf("%d", &n);
init();
for (int i = 1, u, v; i <= n-1; i++) {
scanf("%d%d", &u, &v);
addedge(u, v); addedge(v, u);
}
dfs1(0, 1);
dfs2(0, 1, 1);
for (int i = 1; i <= n; i++) printf("%d %d\n", x[i], y[i]);
return 0;
}