Codeforces 1405D Tree Tag 树上思维

首先考虑 链状情况。
当长度与db大于等于2da + 1时Bob获胜,否则Alice获胜。
长度转变为树上直径,即可求解。
考虑初始状态下Alice是否获胜。

#include
#include
#include 
#include 
using namespace std;
#define mp make_pair
#define pb push_back
#define mt(a,b) memset(a,b,sizeof(a))
#define zero(x) (((x)>0?(x):-(x))
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const double pi = 3.14159265;
const double eps = 0.000001;
const ll Mod = 1e9 + 7;
const ll mod = 998244353;
const int maxn = 1e5 + 7;

int t, n;
int k;
vector <int> e[maxn];
int dep[maxn];
int da, db;
int a, b;
int u, v;
void work(int x, int p)
{
     
    for(auto t : e[x])
    {
     
        if(t != p)
        {
     
            dep[t] = dep[x] + 1;
            work(t, x);
        }
    }
}
int main()
{
     
    scanf("%d", &t);
    dep[0] = 0;
    while(t --)
    {
     
        scanf("%d", &n);
        scanf("%d%d%d%d", &a, &b, &da, &db);
        for(int i = 0; i <= n; i ++)
            e[i].clear();
        for(int i = 1; i < n; i ++)
        {
     
            scanf("%d%d", &u, &v);
            e[u].pb(v);
            e[v].pb(u);
        }
        int root = 0;
        dep[1] = 1;
        work(1, -1);

        for(int i = 1; i <= n; i ++)
        {
     
            if(dep[i] > dep[root])
                root = i;
        }
        mt(dep, 0);
        dep[root] = 0;
        work(root, 1);
        int hei = 0;
        for(int i = 1; i <= n; i ++)
        {
     
            if(dep[i] > hei)
                hei = dep[i];
        }
        if(2 * da >= min(db, hei))
        {
     
            printf("Alice\n");
            continue;
        }
        mt(dep, 0);
        dep[a] = 0;
        work(a, -1);
        if(dep[b] <= da)
        {
     
            printf("Alice\n");
        }
        else
            printf("Bob\n");

    }




}


你可能感兴趣的:(随笔)