【D. Tree Tag】
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

浙公网安备 33010602011771号