|
思路:如果Bob能把这棵树分成若干两个一组的点对,那么Bob取得胜利,否则Alice获胜。从树尾往上找,把树分成两两节点一组,看需要切断多少条边。可以先反向存下每个节点的入度和出度,每次从入度为0的节点开始往下划分,每找到两个连接的节点断开一条边。
CODE:
#include<stdio.h>
#include<vector>
#include<string.h>
int vis[510],ans;
bool flag;
int in[510],out[510],pre[510];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,k;
scanf("%d%d",&n,&k);
memset(vis,0,sizeof(vis));
memset(pre,-1,sizeof(pre));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
int a;
for(int i=1; i<n; i++)
{
scanf("%d",&a);
pre[i+1]=a;
in[a]++;
out[i+1]++;
}
if(n%2)
{
printf("Alice\n");
continue;
}
ans=0;
flag=true;
int tmp=0;
while(true)
{
tmp=ans;
for(int i=1; i<=n; i++)
{
if(in[i]==0&&out[i]==1)
{
if(in[pre[i]]>=1)
{
in[pre[i]]=-1;
out[pre[i]]=-1;
vis[i]=1;
vis[pre[i]]=1;
int b=pre[pre[i]];
if(b!=-1)
{
in[b]--;
ans++;
}
}
}
}
if(ans==tmp) break;
}
for(int i=1; i<=n; i++)
{
if(!vis[i])
{
flag=false;
}
}
if(flag)
{
if(ans<=k) printf("Bob\n");
else printf("Alice\n");
}
else
{
printf("Alice\n");
}
}
}
/*
20
2 1
1
3 1
1 2
8 1
1 1 3 2 2 5 6
8 4
1 1 3 2 2 5 6
*/
|