Codeforces Round #668 (Div. 2)D. Tree Tag(树形DP树的直径 + 博弈论)

D. Tree Tag

一、题目大意

给你一棵有n个节点的无向树,两个人Alice和Bob一开始分别在a,b两个节点,Alice一次最多移动da个位置,Bob一次最多移动db个位置。当Alice在某次回合中移动到Bob的位置时,就算Alice获胜,相反Bob获胜。现在Alice先手,问你谁能获胜。

二、题解

  1. d i s ( a , b ) < = d a dis(a,b) <= da 时,Alice在第一回合就能移动到Bob所在的位置。Alice获胜。
  2. < = 2 d a 树的直径 <= 2 * da 时,Alice可以移动到树的直径的中点(Alice的下一步移动范围是整棵树),这样无论Bob处于任何位置时,Alice都可到达Bob的位置。Alice获胜。
  3. 当db <= 2 * da 时,Alice可以追上 Bob。因为Bob不能越过Alice跳到另外一颗字数上
  4. d b > 2 d a db > 2 * da 时并且 case 1 不成立时,Alice不能一次达到Bob,Alice向Bob靠近,当Alice与Bob的距离适中大于ba时,则Bob获胜。设 d i s ( a , v ) = d a + 1 dis(a,v) = da + 1 d b < = d i s ( b , v ) < = d i s ( b , a ) + d i s ( a , v ) < = d a + ( d a + 1 ) < = 2 d a + 1 db <= dis(b,v) <= dis(b,a) + dis(a,v) <= da + (da + 1) <= 2 * da + 1

三、ACcode

/*
 * @Author: NEFU_马家沟老三
 * @LastEditTime: 2020-09-07 11:17:13
 * @CSDN blog: https://blog.csdn.net/acm_durante
 * @E-mail: [email protected]
 * @ProbTitle: 
 */
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
#define lowbit(x) ((x) & -(x))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define mem(a, b) memset(a, b, sizeof(a))
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const double PI = acos(-1.0);
const ll mod = 1e9 + 7;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
template<class T>inline void read(T &res)
{
char c;T flag=1;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}
const int N =2e5+5;
int cnt,head[N];
struct node
{
    int v,next;
}e[N];
void add(int u,int v){
    e[++cnt].v = v;
    e[cnt].next = head[u];
    head[u] = cnt;
}
int dp1[N],dp2[N],dp3[N], maxx;//dp1 i节点到叶子的最大距离,dp2是次大距离,maxx是树的直径
//dp3是从i到a的最短距离
void dfs(int u,int fa){
    for(int i = head[u]; ~i ; i = e[i].next){
        int v = e[i].v;
        if(v == fa) continue;
        dp3[v] = dp3[u] + 1; 
        dfs(v,u);
        if(dp1[u] < dp1[v] + 1){
            dp2[u] = dp1[u];
            dp1[u] = dp1[v] + 1;
        }
        else if(dp2[u] < dp1[v] + 1){
            dp2[u] = dp1[v] + 1;
        }
        maxx = max(maxx,dp1[u] + dp2[u]);
    }
}
int main()
{
    IOS
    int t;
    cin >> t;
    while(t--){
        cnt = 0;
        maxx = 0;
        int n,a,b,da,db;
        mem(head,-1);
        mem(dp1,0);
        mem(dp2,0);
        mem(dp3,0);
        cin >> n >> a >> b >> da >> db;
        rep(i,1,n-1){
            int u,v;
            cin >> u >> v;
            add(u,v), add(v,u);
        }
        dfs(a,-1);
        if(da * 2 >= min(maxx,db) || da >= dp3[b] ) cout << "Alice\n";
        else cout << "Bob\n";
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/acm_durante/article/details/108443136
今日推荐