题目意思就是给你一颗树,
Bob可以在树上染色,就是选择一个点,并且将其周围的点涂黑
Alice可以将树上的一个点涂白
Bob还可以做一个操作,就是剪枝,剪枝之后影响的只是涂黑的操作,就是比如我涂一个点本来可以把周围的点全部染黑的,现在就是减掉的部分就不能染黑了
最后,当树全部都被涂完的话,我们就找树上有没有白点,如果有那么Alice赢了,否则就是Bob赢
那么题解就是判断,分m次能不能把这棵树分为只有两两相连的点,能,就Bob赢,否则Alice赢
为什么呢
首先,如果我把一棵树全部分为两两相连的点的话,Bob是肯定能赢的
如果不能分为两两相连的点
那么最后会只剩一个点或者,超过三个点
一个点的话肯定是Alice赢,超过三个点的话,就一定有一个点他的叶子节点>=2那么Alice把这个点涂白即可
下面是15msAC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#define maxn 600
#define inf 0x3f3f3f3f
using namespace std;
int fa[maxn],m,n;
vector<int> son[maxn];
void DFS(int root)
{
vector<int>::iterator it;
if (son[root].empty())
{
m-=inf;
return;
}
for (it=son[root].begin()+1;it!=son[root].end();it++)
{
m--;
DFS(*it);
}
int ss=*(son[root].begin());
for (it=son[ss].begin();it!=son[ss].end();it++)
{
m--;
DFS(*it);
}
return;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&m);
memset(fa,0,sizeof(fa));
for (int k=0;k<maxn;k++)
son[k].clear();
for (int k=1;k<n;k++)
{
int save;
scanf("%d",&save);
fa[k+1]=save;
son[save].push_back(k+1);
}
DFS(1);
if (m>=0) printf("Bob\n");
else printf("Alice\n");
}
return 0;
}