Problem Description
Alice and Bob are playing a game called ‘Gameia ? Gameia !’. The game goes like this :
0. There is a tree with all node unpainted initial.
1. Because Bob is the VIP player, so Bob has K chances to make a small change on the tree any time during the game if he wants, whether before or after Alice’s action. These chances can be used together or separate, changes will happen in a flash. each change is defined as cut an edge on the tree.
2. Then the game starts, Alice and Bob take turns to paint an unpainted node, Alice go first, and then Bob.
3. In Alice’s move, she can paint an unpainted node into white color.
4. In Bob’s move, he can paint an unpainted node into black color, and what’s more, all the other nodes which connects with the node directly will be painted or repainted into black color too, even if they are white color before.
5. When anybody can’t make a move, the game stop, with all nodes painted of course. If they can find a node with white color, Alice win the game, otherwise Bob.
Given the tree initial, who will win the game if both players play optimally?
Input
The first line of the input gives the number of test cases T; T test cases follow.
Each case begins with one line with two integers N and K : the size of the tree and the max small changes that Bob can make.
The next line gives the information of the tree, nodes are marked from 1 to N, node 1 is the root, so the line contains N-1 numbers, the i-th of them give the farther node of the node i+1.
Limits
T≤100
1≤N≤500
0≤K≤500
1≤Pi≤i
Output
For each test case output one line denotes the answer.
If Alice can win, output “Alice” , otherwise “Bob”.
Sample Input
2
2 1
1
3 1
1 2
Sample Output
Bob
Alice
Source
2017 Multi-University Training Contest - Team 6
Recommend
liuyiding | We have carefully selected several similar problems for you: 6119 6118 6117 6116 6115
这个题花了我半天时间才想明白,在这里我一定要讲得清清楚楚。
题意:
0.给出一个有n个节点的二叉树,二叉树的所有节点都是没有被进行过标记的(没有被染色)。
1.Alice只能将一个未被染色的节点染成白色。但是游戏开始时,Alice先手。
2.Bob是人民币玩家,Bob能将一个未被染色的节点染成黑色,并且感染和这个节点相邻的节点,也使其变成黑色(无论周围的节点是否已经被处理,都被重新染成黑色);另外,Bob还有K次开挂的机会,可以在任意时候使用,就是剪掉一条边,让一棵树变成两棵树…(最后可以变成好多好多颗树= =)
3.当所有的节点都被染过色的时候,若有白色节点则Alice赢,全为黑色则Bob赢,游戏结束。
分析:
1.Alice的角度:我必须每次都染父亲节点 ,这样一来Bob就被我牵着鼻子走。如果有某个节点有两个及其以上孩子节点,Alice必胜(此时Alice的一步操作需要Bob两次弥补,它弥补不过来了,哈哈)。我需要奇数个元素的子树。
2.Bob的角度:我的剪刀可以减掉一条边,但是如果剪下来剩下了单独的点是毫无意义的(要么这个点已经被染过色了,要么这个点会被Alice染成白色就必输了,浪费)。我需要将整个树分成 只有两个节点的 一堆树 。所以,树必须是偶数个节点,K>=n/2-1。如果剪不完,那么在Alice眼里就会存在有奇数子树(把树转90度看= =),就GG了。
总结一下Bob的获胜条件:
1.n为偶数&&被剪后所有子树也都是偶数个节点 直到变成一对一对儿的小树
2.K>=n/2-1;
PS:Bob的剪刀一开始全部用光,不然有可能把自己本可以走的步骤给涂死了= =
这样想比较简单。
其余都是Alice获胜!
AC代码:
#include<iostream>
#include<cstring>
using namespace std;
int n, k;
int T; int temp;
int a[10000];
int sz[10000];
int main()
{
cin >> T;
bool flag = 0;
while (T--)
{
cin >> n >> k;
flag = 0;
memset(a, 0, sizeof(a));
for (int i = 1; i <= n; i++)
{
sz[i] = 1;
}
for (int i = 2; i <= n; i++)
{
cin >> a[i];
}
for (int i = n; i >= 1; i--)
{
if (sz[i] >= 3)
{
flag = 1;
}
sz[a[i]] += (sz[i]%2);//子树4不4偶数树
/*if (sz[i] != 2)
{
sz[a[i]] += 1;
}*/
}
if (flag == 0 && n % 2 == 0 && k >= (n / 2 - 1))
cout << "Bob" << endl;
else
cout << "Alice" << endl;
}
//system("pause");
return 0;
}
标程:
#include <iostream>
using namespace std;
#define rep(i,a,b) for(int i=a;i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
const int N = 1e5 + 10;
int T, n, K, par[N], sz[N];
int main()
{
scanf("%d", &T);
rep(i, 0, T)
{
scanf("%d%d", &n, &K);
rep(i, 2, n + 1)
scanf("%d", par + i);
rep(i, 1, n + 1)
sz[i] = 1;
bool ok = 1;
per(i, 1, n + 1)
ok &= sz[i] <= 2, sz[par[i]] += sz[i] & 1;
puts(n % 2 == 0 && K >= n / 2 - 1 && ok ? "Bob" : "Alice");
}
return 0;
}