题解:qoj8130 Yet Another Balanced Coloring Problem

题意:给你两颗树,满足 \(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
*/
posted @ 2025-07-25 18:19  LUlululu1616  阅读(79)  评论(0)    收藏  举报