思维题,关注一下有哪些输赢关系
1.dis(a,b)<=da,显然,一步就能抓到
2.直径小于2*da,这是本题解题的核心,我们发现alice站在直径的终点就稳赢
3.如果直径大于2*da,我们证明当2*da>=db的时候alice赢,否则bob赢
首先因为我们不在情况2,所以一定可以找到一个点使得这个点与alice相离da+1个位置,并且我们发现如果db>2*da,那么bob永远可以走到这个位置,就是稳赢
如果2*da>=db,alice可以采取策略不断往bob所在子树逼近,因为bob不能跳出掌控的范围,所以bob是必输的
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=4e5+10; const int inf=1e9; int n; int dis[N]; int f[N][2]; int h[N],ne[N],e[N],idx; int res=0; void add(int a,int b){ e[idx]=b,ne[idx]=h[a],h[a]=idx++; } void dfs(int u,int fa){ int i; f[u][0]=f[u][1]=0; for(i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(j==fa) continue; dis[j]=dis[u]+1; dfs(j,u); if(f[j][0]+1>=f[u][0]){ f[u][1]=f[u][0]; f[u][0]=f[j][0]+1; } else if(f[j][0]+1>f[u][1]){ f[u][1]=f[j][0]+1; } } res=max(res,f[u][0]+f[u][1]); } int main(){ ios::sync_with_stdio(false); int t; cin>>t; while(t--){ int a,b,da,db; cin>>n>>a>>b>>da>>db; int i; idx=0; res=0; for(i=1;i<=n;i++){ h[i]=-1; dis[i]=0; } for(i=1;i<n;i++){ int x,y; cin>>x>>y; add(x,y); add(y,x); } dfs(a,-1); int flag=0; if(da>=dis[b]){ flag=1; } if(2*da>=res){ flag=1; } if(2*da>=db){ flag=1; } if(flag){ cout<<"Alice"<<endl; } else{ cout<<"Bob"<<endl; } } return 0; }