题意:有一棵树,Alice和Bob往树上没染过色的节点染色,Alice先手。Alice涂白色,Bob涂黑色。当Bob把一个节点涂成黑色的时候,和这个节点直接相邻的节点也都会变成黑色,无论它原来是没有颜色还是已经被涂成白色。Bob还有k次机会,每次可以去掉树上的一条边,这个机会可以在任何时候使用。如果整棵树上没有没有涂色的节点了,游戏结束,此时若树上有白色的节点,Alice赢,否则Bob赢。
可以想象,如果我把这棵树分成很多个两个两个相连的小树,那么Bob一定赢,因为Alice涂一个点,Bob就涂这个子树上的另一个点,Alice那个点就变成黑的了。所以如果点数为奇数,Alice赢,如果为偶数,则如果有一个节点有两个或以上节点数为奇数的子节点,Alice一定赢。因为两个两个分分到中心一定是菊花状的,没法分成两个两个的,此时Alice只要涂中间节点,Bob就输了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define ll long long
const int maxn=510;
int T;
int N,K;
vector <int> vec[maxn];
int degree[maxn];
bool vis[maxn];
int flag=0;
int main(){
scanf("%d",&T);
while (T--){
scanf("%d %d",&N,&K);
for (int i=1;i<=N;i++){
vec[i].clear();
}
int x;
for (int i=2;i<=N;i++){
scanf("%d",&x);
vec[x].push_back(i);
}
flag=0;
for (int i=1;i<=N;i++){
int cnt=0;
if (vec[i].size()%2==1){
cnt++;
}
if (cnt>=2){
flag=1;
break;
}
}
if (N%2==1) printf("Alice\n");
else if (N/2-1>K) printf("Alice\n");
else if (flag) printf("Alice\n");
else printf("Bob\n");
}
}