AT_hitachi2020_c ThREE
AT_hitachi2020_c ThREE
简单构造题,考虑题目给个限制,那么就是不能存在\(i, j\),\(i\)到\(j\)的距离为\(3\)且\(p_i \equiv p_j \pmod 3\)且\(p_i,p_j\)不为\(3\)的倍数。
那么把数按模\(3\)分类,只需要保证同一类(不包括\(3\)的倍数)的数之间的距离为偶数即可。那么我们可以对树黑白染色,记\(x\)为黑点数量,\(y\)为白点数量。
如果\(x \le \lfloor \dfrac{n}{3} \rfloor\) \(or\) \(y \le \lfloor \dfrac{n}{3} \rfloor\),那么我们可以用\(3\)的倍数填满数量小的,再将其他数放在同一颜色,这样显然,同一类数是距离偶数的。
否则,我们可以将余数为\(1\)放在黑色,余数为\(2\)放在白色,用\(3\)的倍数填剩余的,这样也是显然正确的。
Code
#include<cstdio>
#include<iostream>
#define IN inline
using namespace std;
const int N = 2e5 + 5;
int d[2], vis[N], bz[N], n, h[N], ans[N], tot;
IN int read() {
int res = 0; char ch = getchar();
for (; !isdigit(ch); ch = getchar());
for (; isdigit(ch); ch = getchar()) res = (res << 3) + (res << 1) + (ch ^ 48);
return res;
}
struct edge{int to, nxt;}e[N << 1];
void add(int x, int y){e[++tot] = edge{y, h[x]}, h[x] = tot;}
void dfs(int u, int fa, int cor) {
d[cor]++, vis[u] = cor;
for (int i = h[u]; i; i = e[i].nxt)
if (fa ^ e[i].to) dfs(e[i].to, u, cor ^ 1);
}
int main() {
n = read();
for (int i = 1, q, p; i < n; i++)
q = read(), p = read(), add(q, p), add(p, q);
dfs(1, 0, 0);
if (d[0] > n / 3 && d[1] > n / 3) {
for (int i = 1, j = 1, k = 2; i <= n; i++)
if (vis[i]) ans[i] = j, j += 3;
else ans[i] = k, k += 3;
for (int i = 1, j = 3; i <= n; i++)
if (ans[i] > n) ans[i] = j, j += 3;
}
else {
int fl = 0;
if (d[1] <= n / 3) fl = 1;
for (int i = 1, j = 3; i <= n; i++)
if (vis[i] == fl) ans[i] = j, bz[j] = 1, j += 3;
for (int i = 1, j = 1; i <= n; i++) {
if (!ans[i]) {
while (bz[j]) j++; ans[i] = j, bz[j] = 1;
}
}
}
for (int i = 1; i <= n; i++) printf("%d ",ans[i]);
}

浙公网安备 33010602011771号