1. 程式人生 > 實用技巧 >CF1405D Tree Tag(樹的直徑+博弈,慘痛的失利)

CF1405D Tree Tag(樹的直徑+博弈,慘痛的失利)

題意:

給出一棵樹和兩個人的初始位置,a去抓b,a一次最多移da,b一次最多移db,詢問在無限次操作內a是否能抓到b。

題解:

如果一步就能抓到,則輸出Alice。

如果da*2大於等於樹的直徑,也輸出Alice。

如果da*2大於等於樹的直徑,也輸出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"); } } } }