题意:给你两颗树,满足 \(1,2\cdots k\) 在两棵树中都是叶子,现在要求给叶子染上黑/白,满足对于两棵树中的每个节点,子树中的黑/白点数量之差不超过 \(1\),给出构造。
做法:
看到黑白差不大于 \(1\),这个东西很经典的是在限制的之间连边,然后跑二分图染色即可。
那么我们考虑对于两棵树分开连,我们假设子树内目前有若干个叶子没有处理,那么我们就让他们随机两两配对在一起,多余的一个就没必要限制,让他交给父亲去处理即可,容易说明这样是合法的。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
int n, m, col[maxn], cnt, fl = 0;
vector<int> e[maxn], g[maxn], h[maxn];
int dfse(int u) {if(e[u].size() == 0 && u != n)return u;vector<int> pos;for (int i = 0; i < e[u].size(); i++) {int v = e[u][i];int d = dfse(v);if(d)pos.push_back(d);}for (int i = 0; i < (int)pos.size() - 1; i += 2)h[pos[i]].push_back(pos[i + 1]), h[pos[i + 1]].push_back(pos[i]);if(pos.size() % 2)return pos[pos.size() - 1];return 0;
}
int dfsg(int u) { if(g[u].size() == 0 && u != m)return u;vector<int> pos;for (int i = 0; i < g[u].size(); i++) {int v = g[u][i];int d = dfsg(v);if(d)pos.push_back(d);}
// cout << u << " " << pos.size() << endl; for (int i = 0; i < (int)pos.size() - 1; i += 2)h[pos[i]].push_back(pos[i + 1]), h[pos[i + 1]].push_back(pos[i]);if(pos.size() % 2)return pos[pos.size() - 1];return 0;
}
void dfs(int u, int c) {col[u] = c;for (int i = 0; i < h[u].size(); i++) {int v = h[u][i];if(col[v])continue;dfs(v, 3 - c);}
}
int nw = 0;
void solve() {cnt = 0;nw++;cin >> n >> m;
// if(fl && nw == 207)
// cout << n << " " << m << endl;for (int i = 1; i <= n; i++)e[i].clear(), h[i].clear(), col[i] = 0;for (int i = 1; i <= m; i++)g[i].clear(), h[i].clear();for (int i = 1; i < n; i++) {int f; cin >> f;e[f].push_back(i);
// if(fl && nw == 207)
// cout << f << " ";}
// if(fl && nw == 207)
// cout << endl;for (int i = 1; i < m; i++) {int f; cin >> f;g[f].push_back(i);
// if(fl && nw == 207)
// cout << f << " ";}dfse(n), dfsg(m);for (int i = 1; i < n; i++)cnt += (e[i].size() == 0);for (int i = 1; i <= cnt; i++)if(!col[i])dfs(i, 1);
// if(!fl || (fl && nw == 207)) {for (int i = 1; i <= cnt; i++)cout << (col[i] == 1 ? "R" : "B");cout << endl;
// if(fl && nw == 207) {
// for (int i = 1; i <= n; i++)
// for (int j = 0; j < h[i].size(); j++)
// cout << i << " " << h[i][j] << endl;
// }
// }
}
int main() {int T; cin >> T;fl = (T > 100);while(T--)solve();return 0;
}
/*
2
7 7
5 5 6 6 7 7
5 6 5 6 7 7
5 4
4 4 5 5
4 4 4
*/