[CF1404B] Tree Tag - 博弈论,树的直径
Description
给定一棵树,Alice 和 Bob 初始在 a,b 两点,每次移动的距离分别不超过 da,db,如果 Alice 能在 \(10^{100}\) 轮内追到 Bob 那么 Alice 赢,否则 Bob 赢。判断输赢。
Solution
如果 da >= dist(a,b),那么一步结束
如果 2 da >= diam,A 走到直径中点,那么下一步 A 一定能追到 B
如果 2 da >= db,A 不断逼近 B,最终 B 逃不出 A 下一步能走到的范围
其它情况下 B 在 A 靠近他时反向跳走,不会使得距离减小(否则必然满足上述条件中的一个)
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1000005;
int n, a, b, da, db, d[N];
vector<int> g[N];
void dfs(int p, int from)
{
for (int q : g[p])
if (q != from)
{
d[q] = d[p] + 1;
dfs(q, p);
}
}
void solve()
{
cin >> n >> a >> b >> da >> db;
for (int i = 1; i <= n; i++)
g[i].clear();
for (int i = 1; i < n; i++)
{
int x, y;
cin >> x >> y;
g[x].push_back(y);
g[y].push_back(x);
}
int pt = 0;
d[1] = 0;
dfs(1, 0);
pt = max_element(d + 1, d + n + 1) - d;
int diam = 0;
d[pt] = 0;
dfs(pt, 0);
diam = *max_element(d + 1, d + n + 1);
db = min(db, diam);
int dab = 0;
d[a] = 0;
dfs(a, 0);
dab = d[b];
if (da >= dab || 2 * da >= db)
cout << "Alice" << endl;
else
cout << "Bob" << endl;
}
signed main()
{
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--)
{
solve();
}
}