给你一棵树,一个人(\(Alice\))在 \(a\) 处,一个人(\(Bob\))在 \(b\) 处,其中 \(a\) 每次可以移动到距离(经过的边的个数)为 \(da\) 以内的任意一个点上,\(b\) 每次可以移动到距离为 \(db\) 以内的任意一个点上。
在 \(a\) 上的人 \(Alice\) 先移动,问 \(A\) 能否在有限次的移动过后和 \(Bob\) 在同一个节点上,如果能够做到, 那么 \(A\) 赢,否则 \(B\) 赢。\(A\) 和 \(B\) 都会采取有利于自己的最佳策略。
问你最后谁会赢。
我们分成 \(4\) 类情况讨论:
求出 \(a\) 到 \(b\) 的距离和 \(da\) 判断一下,然后求出树的直径, 和 \(2\times da\) 比较一下, 最后用 \(2 \times da\) 再和 \(db\) 比较一下就可以了。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5;
int n,a,b,da,db,d1,d2,nextX;
vector<int> g[N + 10];
void dfs1(int x,int fa,int mydis){
if (x == b){
d1 = mydis;
return;
}
int len = g[x].size();
for (int i = 0;i < len; i++){
int y = g[x][i];
if (y == fa){
continue;
}
dfs1(y,x,mydis + 1);
}
}
void dfs2(int x,int fa,int mydis){
if (mydis > d2){
nextX = x;
d2 = mydis;
}
int len = g[x].size();
for (int i = 0;i < len; i++){
int y = g[x][i];
if (y == fa){
continue;
}
dfs2(y,x,mydis+1);
}
}
int main(){
#ifdef LOCAL_DEFINE
freopen("E://9.AlgorithmCompetition//Visitor.txt","r",stdin);
#endif
ios::sync_with_stdio(0),cin.tie(0);
int T;
cin >> T;
while (T--){
for (int i = 1;i <= n; i++){
g[i].clear();
}
cin >> n >> a >> b >> da >> db;
for (int i = 1;i < n; i++){
int x, y;
cin >> x >> y;
g[x].push_back(y);
g[y].push_back(x);
}
dfs1(a, -1, 0);
if (da >= d1){
cout << "Alice" << endl;
continue;
}
d2 = 0;nextX = 1;
dfs2(a,-1,0);
d2 = 0;
dfs2(nextX,-1,0);
if (2*da >= d2){
cout << "Alice" << endl;
continue;
}
if (db > da*2){
cout << "Bob" << endl;
}else{
cout << "Alice" << endl;
}
}
return 0;
}
【Codeforces Round #668 (Div. 2) D】Tree Tag
原文:https://www.cnblogs.com/AWCXV/p/13634726.html