一. 题目
二. 思路
(1)B要先去和A回合,因为B只能将红染成蓝,不能直接将白染成蓝,所以B必须走A走过的路才有效。
(2)答案分为两部分,去和A回合的最短距离 + 以回合点为根节点,遍历整棵树的距离
(3)其中遍历整棵树的最短距离为(边数 - 1) * 2 + 从根节点到最远的叶子节点的距离,因为走到一个叶子节点就会返回,回到根节点再去下一个叶子节点,因此所有边都会走两遍,但可以选一个最远的叶子节点最后一个走,到达后就留在那里不回根节点了。
三. 代码
(1)dfs1 找回合点,vector变量pash保存路径,计算A与B之间的距离。
(2)dfs2 找数的最深深度。
(3)向上取整公式:(n + 1)/ 2 - 1
#include<bits/stdc++.h>
#define LL long long
using namespace std;
int n, a, b, x, y, mid, mx, dis, ans;
vector<int> G[200005];
vector<int> path;
void dfs1(int u,int fa)
{
path.push_back(u);
if (u == b)
{
mid = path[(path.size() + 1) / 2 - 1];
dis = path.size() / 2;
}
for (auto v : G[u])
{
if (v == fa)
continue;
dfs1(v, u);
}
path.pop_back();
}
void dfs2(int u, int fa, int dep)
{
mx = max(mx, dep);
for (auto v : G[u])
{
if (v == fa)
continue;
dfs2(v, u, dep + 1);
}
}
int main()
{
cin >> n >> a >> b;
for (int i = 1; i <= n - 1; i ++)
{
cin >> x >> y;
G[x].push_back(y);
G[y].push_back(x);
}
if (a == b)
{
dfs2(a, -1, 0);
ans = 2 * (n - 1) -mx;
cout << ans;
return 0;
}
dfs1(a, -1);
ans += dis;
dfs2(mid, -1, 0);
ans += 2 * (n - 1) -mx;
cout << ans;
return 0;
}