【D. Tree Tag】
阿新 • • 發佈:2020-09-07
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