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\n",d); //d--; if (dis[b]<=da) { printf("Alice\n"); continue; } if (da>=db) { printf("Alice\n"); continue; } else { if (da*2>=d) { printf("Alice\n"); continue; } else if (db<=da*2) { printf("Alice\n"); } else { printf("Bob\n"); } } } }