CSP - J day4

 一. 题目

二. 思路

 (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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值