[CF2040D] Non Prime Tree 题解
传送门
构造题做得较少,所以性质观察得较慢。
值域给的
按深度记录下每层结点,发现隔一层依次按
即:先填奇数层,再填偶数层。
但是连续的偶数是不能相邻的,发现当深度在
处理方法:
我们尽量让出问题的结点在度最小的结点。这样就可以调整最少数量的结点。
方便起见,尽量让根结点的度最小。我们只需指定一个叶结点为新根即可,按新根计算深度等。
于是按树的深度
时,直接按层填充。 时,直接输出1 2\n
。 时,按层数 填,再把根结点减一。 时,按层数 填,再把根结点加一。
做完了。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define Linf 0x3f3f3f3f3f3f3f3f
#define pii pair<int, int>
#define all(v) v.begin(), v.end()
using namespace std;
//#define filename "xxx"
#define FileOperations() freopen(filename".in", "r", stdin), freopen(filename".out", "w", stdout)
namespace Traveller {
const int N = 2e5+2;
int n;
vector<int> g[N];
int dep[N], leaf, mxd;
void DFS1(int u, int fa) {
leaf = u;
for(auto v : g[u]) {
if(v == fa) continue;
DFS1(v, u);
}
}
vector<int> p[N];
void DFS2(int u, int fa) {
dep[u] = dep[fa] + 1;
mxd = max(mxd, dep[u]);
p[dep[u]].push_back(u);
for(auto v : g[u]) {
if(v == fa) continue;
DFS2(v, u);
}
}
int a[N];
void main() {
cin >> n;
for(int i = 1; i <= n; ++i) g[i].clear(), p[i].clear();
for(int i = 1, u, v; i < n; ++i) {
scanf("%d%d", &u, &v);
g[u].push_back(v), g[v].push_back(u);
}
mxd = 0;
DFS1(1, 0), DFS2(leaf, 0);
if(mxd == 2) printf("1 2\n");
else if(mxd == 3) {
int k = 2;
a[p[2][0]] = k, k += 2;
a[p[1][0]] = k-1, k += 2;
for(auto u : p[3]) a[u] = k, k += 2;
for(int i = 1; i <= n; ++i) printf("%d ", a[i]);
puts("");
}
else if(mxd == 4) {
int k = 2;
for(auto u : p[3]) a[u] = k, k += 2;
a[p[1][0]] = k+1, k += 2;
a[p[2][0]] = k, k += 2;
for(auto u : p[4]) a[u] = k, k += 2;
for(int i = 1; i <= n; ++i) printf("%d ", a[i]);
puts("");
}
else {
int k = 2;
for(int d = 1; d <= mxd; d += 2)
for(auto u : p[d]) a[u] = k, k += 2;
for(int d = 2; d <= mxd; d += 2)
for(auto u : p[d]) a[u] = k, k += 2;
for(int i = 1; i <= n; ++i) printf("%d ", a[i]);
puts("");
}
}
}
signed main() {
#ifdef filename
FileOperations();
#endif
int _;
cin >> _;
while(_--) Traveller::main();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步