链接
https://ac.nowcoder.com/acm/contest/5674/K
题意
树根为 $1$,A 在 $1$,B 在 $n$,A 每秒走 $1$ 步,B 每秒走 $2$ 步,开始时 A 向 B 走,经过 $t$ 秒后,B 去追 A,A 随意移动或者不移动使自己不被 B 抓到,问 B 最晚经过几秒抓到 A
思路
以 $n$ 为根 DFS,计算每个点到 $n$ 的距离
找到 $t$ 秒后 A 的位置,从这个点开始 BFS,如果被抓到了,则更新答案,否则继续 BFS,当走到叶子节点还没被抓到,那么 B 走到该叶子节点的时间就是抓到 A 的时间,也更新一下答案
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
   | #include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define fi first #define se second typedef long long ll; typedef pair<int,int> pii; typedef vector<int> vi;
  const int N=1e5+5; int n,t,dist[N],fa[N],mx[N]; vi G[N]; bool st[N]; void dfs(int u) {     for(auto v:G[u]) {         if(v==fa[u]) continue;         fa[v]=u;         dist[v]=dist[u]+1;         dfs(v);     } } int find(int u) {      for(int i=1;i<=t;i++) u=fa[u];     return u; } void bfs() {     int res=0;     int s=find(1);     queue<pii> q;     q.push(mp(s,0));     st[s]=true;     while(q.size()) {         auto x=q.front();         q.pop();         if(2*x.se>=dist[x.fi]) {res=max(res,x.se);continue;}         else {             bool f=false;             for(auto v:G[x.fi]) if(!st[v]) f=true,st[v]=true,q.push(mp(v,x.se+1));             if(!f) res=max(res,(dist[x.fi]+1)>>1);         }     }     printf("%d\n",res); } int main() {     scanf("%d%d",&n,&t);     for(int i=1;i<n;i++) {         int u,v;         scanf("%d%d",&u,&v);         G[u].pb(v);         G[v].pb(u);     }     for(int i=1;i<=n;i++) fa[i]=i;     dfs(n);      bfs();     return 0; }
   |