Loading

【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

posted @ 2020-09-07 15:27  —O0oO-  阅读(402)  评论(0)    收藏  举报