首先,我们将题目理解成若\(i\)与\(j\)距离恰好为\(3\),则不可能\(p_i \equiv p_j \equiv 1 \space or \space 2 (\bmod 3)\)。这就相当于我们要构造一个大小为\([\frac{n + 1}{3}]\)的点集\(A_2\),用来放所有模3余2的数,再构造一个大小为\([\frac{n + 2}{3}]\)的点集\(A_1\),用来放所有模3余1的数。需要满足这两个集合交集为空,且若\(i\)与\(j\)距离为\(3\),则它们不在同一个集合内。

发现距离为\(3\)的点连成的图性质是不好的,唯一好的性质就是:它是二分图。我们不妨大胆地把条件加强为:构造这样的点集\(A_1, A_2\),使得它们全部再二分图的同一边。

我们把树按深度奇偶染色,不妨设染一种颜色的点数为\(X\),另一种为\(Y\),且\(X \leq Y\)。

若\(X \ge [\frac{n + 1}{3}]\)且\(Y \ge [\frac{n + 2}{3}]\),我们就在\(X\)中任意取\([\frac{n + 1}{3}]\)个点作为\(A_2\),在\(Y\)中任意取\([\frac{n + 2}{3}]\)个点作为\(A_1\)即可。

否则我们容易证明\(Y \ge [\frac{n + 1}{3}] + [\frac{n + 2}{3}]\),在\(Y\)中任意找两个集合的点即可。

代码如下:

#include <bits/stdc++.h>
using namespace std; const int N = 200005; template <class T>
void read (T &x) {
int sgn = 1;
char ch;
x = 0;
for (ch = getchar(); (ch < '0' || ch > '9') && ch != '-'; ch = getchar()) ;
if (ch == '-') ch = getchar(), sgn = -1;
for (; '0' <= ch && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
x *= sgn;
}
template <class T>
void write (T x) {
if (x < 0) putchar('-'), write(-x);
else if (x < 10) putchar(x + '0');
else write(x / 10), putchar(x % 10 + '0');
} struct edge {
int to, nxt;
} tree[N << 1];
int n, col[N], head[N], perm[N], cnt = 0, cnt0 = 0, cnt1 = 0;
void addedge (int u, int v) {
edge e = {v, head[u]};
tree[head[u] = cnt++] = e;
} void dfs (int u, int fa) {
for (int i = head[u]; ~i; i = tree[i].nxt) {
int v = tree[i].to;
if (v != fa) {
col[v] = col[u] ^ 1;
dfs(v, u);
}
}
} int main () {
read(n);
for (int i = 1; i <= n; i++) head[i] = -1; for (int i = 1; i < n; i++) {
int u, v;
read(u), read(v);
addedge(u, v), addedge(v, u);
}
col[1] = 0, dfs(1, 0); for (int i = 1; i <= n; i++) {
if (col[i] == 0) cnt0++;
else cnt1++;
} if (cnt0 > cnt1) {
for (int i = 1; i <= n; i++) col[i] ^= 1;
swap(cnt0, cnt1);
}
int bound0 = n / 3, bound1 = (n + 1) / 3, bound2 = (n + 2) / 3;
if (cnt0 >= bound1 && cnt1 >= bound2) {
int tot0 = 0, tot1 = 0, tot2 = 0;
for (int i = 1; i <= n; i++) {
if (col[i] == 0) {
if (tot2 >= bound1) perm[i] = 3 * ++tot0;
else perm[i] = 3 * ++tot2 - 1;
}
else {
if (tot1 >= bound2) perm[i] = 3 * ++tot0;
else perm[i] = 3 * ++tot1 - 2;
}
}
}
else {
int tot0 = 0, tot1 = 0, tot2 = 0;
for (int i = 1; i <= n; i++) {
if (col[i] == 0) perm[i] = 3 * ++tot0;
else {
if (tot1 < bound2) perm[i] = 3 * ++tot1 - 2;
else if (tot2 < bound1) perm[i] = 3 * ++tot2 - 1;
else perm[i] = 3 * ++tot0;
}
}
}
for (int i = 1; i <= n; i++) write(perm[i]), putchar(' ');
putchar('\n');
return 0;
}

最新文章

  1. js中网页高度与宽度那些事
  2. phpMyAdmin上传文件大小限制
  3. spark1.5.1环境搭建
  4. jQuery.hhNewSilder 滚动图片插件
  5. ASP.NET MVC 后台接收集合参数和 jquery ajax 传值
  6. Microsoft Visual Studio 6.0 Enterprise Edition
  7. VC POST表单——登录验证新浪邮箱
  8. React+Redux学习笔记:React+Redux简易开发步骤
  9. jquery.jqprint-0.3.js打印table表格遇到的坑
  10. 状压DP小结
  11. 流式处理的新贵 Kafka Stream - Kafka设计解析(七)
  12. [LOJ 6185]烷基计数
  13. 性能测试学习 第九课--LR12中controller基础知识
  14. idea 方便的设置代码段
  15. CentOS 6与7对比【转】
  16. 学习newton raphson and back eluer
  17. 《嵌入式系统原理与接口技术》&mdash;&mdash;嵌入式系统接口应用基础
  18. Dubbo调用链(version:2.5.3)
  19. 974. Subarray Sums Divisible by K
  20. powerdesigner基础操作

热门文章

  1. Internet 网络协议族
  2. mysql之优化器、执行计划、简单优化
  3. Python_PyQt5_库
  4. [Kafka][1][初识Kafka]
  5. Mysql预处理语句prepare、execute、deallocate
  6. 深度分享:面试阿里,字节跳动,美团90%会被问到的HashMap知识
  7. Elements-of-Python01_Input/Output
  8. H5时代leaflet中还在用DivIcon?
  9. FL Studio中有关减少CPU占用率的一些技巧
  10. guitar pro系列教程(二十):Guitar Pro使用技巧之使用向导