题目描述 Alice 和 Bob 又在玩博弈游戏,这时候 Eve 走了进来,拍了拍他俩的肩膀:“我刚研究出一个高明的博弈游戏,要不你们来玩玩?”
Alice 和 Bob 还未反应过来,就被 Eve 带到了一棵有 n 个点,编号从 1到 n的无根树旁边。Eve 介绍道:“树的每个点上都有若干个传送门。你们先把我手上这颗棋子放到树的一个点 u 上,然后我们轮流操作,每次操作时设棋子当前所在位置为 ,则选择一个 v 上的未被使用的传送门把棋子传送到一个与 v 有边相连的点上。不能操作的人就输了!考虑到你们是新手,第一次操作就由你们来完成吧。“
对两位博弈大师来说,赢显然是太简单了。他们现在要研究的是把棋子放在哪些点上才一定能赢。你也能像他们一样推敲出结果吗? 输入格式 从文件 door.in 中读取数据。
第一行输入一个正整数v n,表示无根树的点数。
接下来一i a入 n 个正整数,i 个正整数 表示第 i 个点上传送门的个数。
接下来 n-1行,第 i 行输入两个正整数 ,表示有一条连接点 a 与 b 的边。 输出格式 输出到文件 door.out 中。
输出一个长度为 n 的 01 字符串,在一开始把棋子放在点 i 必胜则第 i 个字符为 1,否则为 0。
#include <bits/stdc++.h>
#define fr(x) \
freopen(#x ".in", "r", stdin); \
freopen(#x ".out", "w", stdout);
using namespace std;
int num[200001];
map<int, int> win;
int main() {
map<int, int> a;
int n;
fr(door) cin >> n;
for (int i = 1; i <= n; i++) {
cin >> num[i];
win[num[i]] = 1;
}
for (int i = 1; i <= n - 1; i++) {
int c, d;
cin >> c >> d;
a[num[c]]++;
a[num[d]]++;
}
sort(num + 1, num + 1 + n);
win[num[1]] = 0;
for (int i = 2; i < n; i++) {
if (win[num[i + 1]] && win[num[i - 1]])
win[num[i]] = 0;
if (a[num[i + 1]] >= a[num[i]] && a[num[i - 1]] >= a[num[i]])
win[num[i]] = 0;
}
for (int i = 1; i <= n; i++) {
cout << win[num[i]];
}
return 0;
}