题意:给出一棵树,将这棵树的节点放在一个1000000×201000000×20的网格中,每个格只能有一个节点,使得树边不相交(树边为线段),输出一种方案。
思路:考虑到树链剖分,一整条路径最多有logn个轻链,所以只需要在每次轻链时换到下一列即可
代码:
vector<int> h[N];
int sz[N], hs[N];
int now[N];
pair<int,int> ans[N];
void dfs1(int u, int f)
{
sz[u] = 1, hs[u] = -1;
for(auto v : h[u])
{
if(v == f) continue;
dfs1(v, u);
sz[u]+=sz[v];
if(hs[u] == -1 || (sz[v] > sz[hs[u]])) hs[u] = v;
}
}
void dfs2(int u, int f, int d)
{
now[d]++;
ans[u] = {now[d], d};
for(auto v : h[u])
{
if(v == f || v == hs[u]) continue;
dfs2(v, u, d + 1);
}
if(hs[u]!=-1) dfs2(hs[u], u, d);
}
void solve()
{
int n;
cin >>n;
for(int i = 1; i < n; ++i)
{
int a, b;
cin >>a >>b;
h[a].push_back(b);
h[b].push_back(a);
}
dfs1(1, 0);
dfs2(1, 0, 1);
for(int i = 1; i <= n; ++i)
{
cout<<ans[i].x<<' '<<ans[i].y<<endl;
}
}