Atcoder ARC162C Mex Game on Tree

发布时间 2023-07-09 00:36:19作者: lhzawa

发现如果子树内如果存在 \(k\)\(mex\) 的值必定不为 \(k\),所以 Bob 的策略即为在空位填上 \(k\)

Alice 的决策便可以知道是在 Bob 出手前就要让这个子树满足条件,不让 Bob 破坏这个子树,考虑需满足哪些条件:

  • 至多 \(1\) 个空位,否则 Bob 可以把 \(k\) 填在子树中。
  • 子树内本身没有颜色为 \(k\) 的点。
  • 空位填上合适的颜色能使 \(0\sim k - 1\) 的颜色都在子树内出现。

这些条件暴力统计即可。
若满足条件,则 Alice 胜,否则 Bob 胜。

时间复杂度 \(O(n(n + k))\)

// lhzawa(https://www.cnblogs.com/lhzawa/)
// Problem: C - Mex Game on Tree
// Contest: AtCoder - AtCoder Regular Contest 162
// URL: https://atcoder.jp/contests/arc162/tasks/arc162_c
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
basic_string<int> G[N];
int col[N];
int mex[N];
int main() {
	function<void ()> solve = []() -> void {
		int n, k;
		scanf("%d%d", &n, &k);
		for (int i = 1; i <= n; i++) {
			G[i].clear();
		}
		for (int i = 2; i <= n; i++) {
			int f;
			scanf("%d", &f);
			G[f] += i;
		}
		for (int i = 1; i <= n; i++) {
			scanf("%d", &col[i]);
		}
		int Yes = 0;
		function<int (int)> dfsmex = [&dfsmex, &k](int u) -> int {
			int tot = (col[u] == -1);
			if ((~ col[u]) && col[u] <= k) {
				mex[col[u]] = 1;
			}
			for (int v : G[u]) {
				tot += dfsmex(v);
			}
			return tot;
		};
		function<void (int)> dfs = [&dfs, &dfsmex, &Yes, &k](int u) -> void {
			for (int v : G[u]) {
				dfs(v);
			}
			for (int i = 0; i <= k; i++) {
				mex[i] = 0;
			}
			int tot = dfsmex(u);
			int cnt = 0;
			for (int i = 0; i < k; i++) {
				cnt += (mex[i] == 0);
			}
			if (((tot == 1 && cnt <= 1) || (tot == 0 && cnt == 0)) && (! mex[k])) {
				Yes = 1;
			}
			return ;
		};
		dfs(1);
		printf("%s\n", Yes ? "Alice" : "Bob");
		return ;
	};
	int _;
	scanf("%d", &_);
	for (; _; _--) {
		solve();
	}
	return 0;
}