传送门:题目
题意:
一棵树,两个点,一个点a想尽快靠近另一个点b,一个点想尽快远离一个点,问这两个点走多少步能碰上。
题解:
因为是一棵树,所以不存在环,一定有解。再脑补一下过程,肯定是:尽快靠近的那个点每一步都是沿最短路径靠近,尽快远离那个点每一步都朝树的边缘走去,走到边缘后就不动了,静静等待。所以最长路径取决与a点走多少步,理解这点是整个问题的核心,所以我们只需要dfs两个点,找到两个点到任意点的距离,然后取dis[a] ≥ ≥ dis[b]的点,然后取这些点的dis[a]的最大值,最后不要忘记乘2,因为dis[a]只是a走过的距离,而题目要求输出a和b的总距离
AC代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#define debug(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 200010;
int n, x;
vector<int> edge[maxn];
int dis[2][maxn];
void dfs(int u, int v, int dist, int flag) {
dis[flag][v] = dist;
for (auto vv : edge[v])
if (vv != u)
dfs(v, vv, dist + 1, flag);
}
int main(void) {
cin >> n >> x;
int t1,t2;
for (int i = 0; i < n - 1; i++) {
cin >> t1 >> t2;
edge[t1].push_back(t2);
edge[t2].push_back(t1);
}
dfs(1, 1, 0, 0); //dist尽可能短
dfs(x, x, 0, 1); //dist尽可能长
int mmax = 0;
for(int i=1;i<=n;i++)
if(dis[1][i]<dis[0][i])
mmax=max(mmax,dis[0][i]*2);
cout<<mmax<<endl;
return 0;
}