http://acm.hdu.edu.cn/showproblem.php?pid=6105
若树可以通过剪边分为若干个两个节点相连的集合,且k大于等于剪边次数,则Bob赢。剩下的情况皆为Alice赢
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int N=505;
const int inf=0x3f3f3f3f;
int vis[N];
vector<int>v[N];
queue<int>q;
void clear(queue<int>& q) {
queue<int> empty;
swap(empty, q);
}
int main(){
std::ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T,n,k,d;
cin>>T;
while(T--){
cin>>n>>k;
for(int i=0;i<=n;i++){
v[i].clear();
vis[i]=0;
}
clear(q);
for(int i=2;i<=n;i++){
cin>>d;
v[i].push_back(d);
v[d].push_back(i);
}
for(int i=1;i<=n;i++){
if(v[i].size()==1){
q.push(i);
}
}
int flag=1;
while(!q.empty()&&flag){
int num=0,p;
int t=q.front();
q.pop();
if(vis[t]) continue;
for(int i=0;i<v[t].size();i++){
if(vis[v[t][i]]==0){
num++;
p=v[t][i];
}
}
if(num==1){
vis[t]=1;
vis[p]=1;
num=0;
for(int i=0;i<v[p].size();i++){
if(vis[v[p][i]]==0){
q.push(v[p][i]);
}
}
}
else if(num==0)
flag=0;
else
q.push(t);
}
if(flag==1){
for(int i=1;i<=n;i++){
if(vis[i]==0){
flag=0;
}
}
}
if(flag&&k>=n/2-1) cout<<"Bob"<<endl;
else cout<<"Alice"<<endl;
}
return 0;
}