【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) 的范围

求出树的直径就可以

  1. 先dfs一遍,找出最远的点,在dfs这个最远的点。两遍dfs
  2. 直接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

原文地址:https://www.cnblogs.com/sduwh/p/13627170.html