一. 题目
二. 思路
(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;
}