CF1405D Tree Tag(树的直径+博弈,惨痛的失利)

题意:

给出一棵树和两个人的初始位置,a去抓b,a一次最多移da,b一次最多移db,询问在无限次操作内a是否能抓到b。

题解:

如果一步就能抓到,则输出Alice。

如果da*2大于等于树的直径,也输出Alice。

如果da*2大于等于db,也输出Alice。

改了一晚上,早上起来发现是DFS部分打错了,博弈思路没有问题。

惨痛的失利,也算是成长吧。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+100;
int t;
int n,a,b,da,db;
vector<int> g[maxn];
int d;
int dp[2][maxn];
int dis[maxn];
void dfs (int u,int pre) {
    for (int v:g[u]) {
        if (v==pre) continue;
        dis[v]=dis[u]+1;
        dfs(v,u);
        if (dp[0][v]+1>dp[0][u]) {
            dp[1][u]=dp[0][u];
            dp[0][u]=dp[0][v]+1;
        }
        else if (dp[0][v]+1>dp[1][u]) {
            dp[1][u]=dp[0][v]+1;
        }
    }
    d=max(dp[0][u]+dp[1][u],d);
}
int main () {
    scanf("%d",&t);
    while (t--) {
        scanf("%d%d%d%d%d",&n,&a,&b,&da,&db);
        d=0;
        for (int i=0;i<=n;i++) dis[i]=0,g[i].clear(),dp[0][i]=0,dp[1][i]=0;
        for (int i=1;i<n;i++) {
            int x,y;
            scanf("%d%d",&x,&y);
            g[x].push_back(y);
            g[y].push_back(x);
        }
        dfs(a,0);
        //printf("%d
",d); 
        //d--;
        if (dis[b]<=da) {
            printf("Alice
");
            continue;
        }
        if (da>=db) {
            printf("Alice
");
            continue;
        }
        else {
            if (da*2>=d) {
                printf("Alice
");
                continue;
            }
            else if (db<=da*2) {
                printf("Alice
");
            }
            else {
                printf("Bob
");
            }
        }
    }
} 
原文地址:https://www.cnblogs.com/zhanglichen/p/13626076.html