题目大意:
有一个土拨鼠在节点1,一个橘子在节点n,在t时刻之前土拨鼠向着n走,橘子不动,从t时刻开始,橘子开始抓土拨鼠,土拨鼠开始跑,土拨鼠 1m/s 橘子 2m/s,问还有多长时间橘子才能抓到土拨鼠。
题解:
首先要求的 t 时刻土拨鼠的位置,然后土拨鼠需要逃跑,所以得与 n 点背向而跑,这时候有俩种可能
- 可供土拨鼠跑的路很长,orange抓到它也没泡到尽头
- 可供土拨鼠跑的路很短,土拨鼠跑到路的尽头等待orange来抓它
所以得求土拨鼠能跑的最远距离, 而且因为背向而跑的,所以他们的相对速度为1m/s,所以orange追上土拨鼠需要花费 (他们 t 时刻相距的距离) 秒。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<queue> 6 #include<cstring> 7 #include<cmath> 8 using namespace std; 9 const int N = 1e5 + 5; 10 11 struct node{int to;}; 12 13 vector <node> G[N]; 14 int d_hog[N], orange[N], f[N]; 15 16 void dfs(int u, int fa, int d[]) { 17 f[u] = fa; 18 for (int i = 0; i < G[u].size(); i++) { 19 int v = G[u][i].to; 20 if (v == fa) continue; 21 d[v] = d[u] + 1; 22 dfs(v, u, d); 23 } 24 } 25 26 void dfs2(int u, int fa, int &maxx) { 27 maxx = max(maxx, orange[u]); 28 for (int i = 0; i < G[u].size(); i++) { 29 int v = G[u][i].to; 30 if (v == fa) continue; 31 dfs2(v, u, maxx); 32 } 33 } 34 35 int main() { 36 int n, t; 37 memset(d_hog, 0, sizeof(d_hog)); 38 memset(orange, 0, sizeof(orange)); 39 40 scanf("%d %d", &n, &t); 41 for (int i = 0; i < n - 1; i++) { 42 int u, v; 43 scanf("%d %d", &u, &v); 44 G[u].push_back({v}); 45 G[v].push_back({u}); 46 } 47 48 dfs(n, n, orange); //遍历organge是希望fa保存orange的父节点 49 int hog_start = 1; 50 while (t--) { //从1向上寻找t次,找到t秒候hog应该在的位置 51 hog_start = f[hog_start]; 52 } 53 int maxx = 0; 54 dfs2(hog_start, f[hog_start], maxx); //求得hog背离n点而行能走的最大距离(这个距离是以n点位参考点) 55 56 int max_dis = maxx - orange[hog_start]; 57 int bw_dis = orange[hog_start]; //t时刻俩者间的距离 58 if (hog_start == n) printf("0\n"); 59 else if (max_dis >= bw_dis) printf("%d\n", max(1, bw_dis)); //表明土拨鼠是在逃跑的路上被捉到的 60 else printf("%d\n", max(1, (max_dis + bw_dis + 1)/ 2)); //表明土拨鼠是在最远处等着orange来捉 61 return 0; 62 }