D. Tree Tag
题意:
(a) , (b) 在树上, 每次最多移动的距离为 (da) , (db) 。 (a) 先行动,问能否在有限次内追上 (b)
打比赛的时候以为是固定距离 (da) , (db)
...
其实想起来也很简单
- 若第一步能抓到, (a) 赢了
- 若 (2da ge Tree Diameter) (树的直径),(a) 赢
- $2da < db $ , (b) 赢了
- (2da ge db) , (a) 赢了
$2da < db $ , (b) 赢了
因为 (b) 可以一直不动,直到 (dis(a,b) le da) ,此时 (b) 可以跳出 (a) 的范围
求出树的直径就可以
- 先dfs一遍,找出最远的点,在dfs这个最远的点。两遍dfs
- 直接dfs
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
vector<int>adj[maxn];
int dep[maxn];
int d;
int dfs(int u,int pre){
int maxpath = 0;
for(int v : adj[u]){
if(v == pre)continue;
dep[v] = dep[u] + 1;
int nowpath = 1 + dfs(v,u);
d = max(d,nowpath + maxpath);
maxpath = max(maxpath,nowpath);
}
return maxpath;
}
int a,b,da,db,n;
int main(){
ios_base::sync_with_stdio(0); //ios_base是父类
//ios::sync_with_stdio(0);
int t;
cin >> t;
while(t--){
cin >> n >> a >> b >> da >> db;
for(int i = 1;i <= n;i++)adj[i].clear();
for(int i = 0;i < n - 1;i++){
int u,v;cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
d = 0;
dep[a] = 0;
dfs(a,-1);
cout << (2*da>=min(d,db) || dep[b] <= da ? "Alice" : "Bob") << endl;
}
}
这个 (dfs) 妙wa