CF1881F Minimum Maximum Distance 题解 贪心+DFS

这篇具有很好参考价值的文章主要介绍了CF1881F Minimum Maximum Distance 题解 贪心+DFS。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Minimum Maximum Distance

传送门

You have a tree with n n n vertices, some of which are marked. A tree is a connected undirected graph without cycles.

Let f i f_i fi denote the maximum distance from vertex i i i to any of the marked vertices.

Your task is to find the minimum value of f i f_i fi among all vertices.

CF1881F Minimum Maximum Distance 题解 贪心+DFS,题解,深度优先,算法,c++,c语言

For example, in the tree shown in the example, vertices 2 2 2, 6 6 6, and 7 7 7 are marked. Then the array f ( i ) = [ 2 , 3 , 2 , 4 , 4 , 3 , 3 ] f(i) = [2, 3, 2, 4, 4, 3, 3] f(i)=[2,3,2,4,4,3,3]. The minimum f i f_i fi is for vertices 1 1 1 and 3 3 3.

Input

The first line contains an integer t t t ( 1 ≤ t ≤ 1 0 4 1 \le t \le 10^4 1t104) — the number of test cases.

The first line of each test case contains two integers n n n and k k k ( 1 ≤ k ≤ n ≤ 2 ⋅ 1 0 5 1 \le k \le n \le 2 \cdot 10^5 1kn2105) — the number of vertices in the tree and the number of marked vertices, respectively.

The second line of each test case contains k k k integers a i a_i ai ( 1 ≤ a i ≤ n , a i − 1 ≤ a i 1 \le a_i \le n, a_{i-1} \le a_i 1ain,ai1ai) — the indices of the marked vertices.

The next n − 1 n - 1 n1 lines contain two integers u i u_i ui and v i v_i vi — the indices of vertices connected by the i i i-th edge.

It is guaranteed that the sum of n n n over all test cases does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2105.

Output

For each test case, output a single integer — the minimum value of f i f_i fi among all vertices.

Examples

input #1

6
7 3
2 6 7
1 2
1 3
2 4
2 5
3 6
3 7
4 4
1 2 3 4
1 2
2 3
3 4
5 1
1
1 2
1 3
1 4
1 5
5 2
4 5
1 2
2 3
1 4
4 5
10 8
1 2 3 4 5 8 9 10
2 10
10 5
5 3
3 1
1 7
7 4
4 9
8 9
6 1
10 9
1 2 4 5 6 7 8 9 10
1 3
3 9
9 4
4 10
10 6
6 7
7 2
2 5
5 8

output #1

2
2
0
1
4
5

input #2

3
6 1
3
1 2
1 3
3 4
3 5
2 6
5 3
1 2 5
1 2
1 3
2 4
3 5
7 1
2
3 2
2 6
6 1
5 6
7 6
4 5

output #2

0
2
0

题目翻译

你有一棵树,树上有 n n n 个顶点,其中一些顶点被做了标记。树是没有循环的连通无向图。

f i f_i fi 表示顶点 i i i 到任何一个有标记顶点的最大距离。

你的任务是找出所有顶点中 f i f_i fi 的最小值。

CF1881F Minimum Maximum Distance 题解 贪心+DFS,题解,深度优先,算法,c++,c语言

例如,在示例所示的树中,顶点 2 2 2 6 6 6 7 7 7 已被标记。然后是数组 f ( i ) = [ 2 , 3 , 2 , 4 , 4 , 3 , 3 ] f(i) = [2, 3, 2, 4, 4, 3, 3] f(i)=[2,3,2,4,4,3,3] 。顶点 1 1 1 3 3 3 的最小值 f i f_i fi

输入格式

第一行包含一个整数 t t t ( 1 ≤ t ≤ 1 0 4 1 \le t \le 10^4 1t104 ) - 测试用例的数量。

每个测试用例的第一行包含两个整数 n n n k k k 1 ≤ k ≤ n ≤ 2 ⋅ 1 0 5 1 \le k \le n \le 2 \cdot 10^5 1kn2105 )–分别是树中的顶点数和标记顶点数。

每个测试用例的第二行包含 k k k 个整数 a i a_i ai ( 1 ≤ a i ≤ n , a i − 1 ≤ a i 1 \le a_i \le n, a_{i-1} \le a_i 1ain,ai1ai ) - 标记顶点的索引。

接下来的 n − 1 n - 1 n1 行包含两个整数 u i u_i ui v i v_i vi --由 i i i /th边连接的顶点的索引。

保证所有测试用例的 n n n 之和不超过 2 ⋅ 1 0 5 2 \cdot 10^5 2105

输出格式

对于每个测试用例,输出一个整数,即所有顶点中 f i f_i fi 的最小值。

以上来自 C o d e F o r c e s ,翻译: D e e p L 以上来自CodeForces,翻译:DeepL 以上来自CodeForces,翻译:DeepL

解题思路

前置知识

  • 树的直径。

正文

(<-你自己的),拿好可以在粗糙物体表面留下痕迹的棍状物体,在一粗糙平面模拟样例(简单来说就是手动模拟样例)可以发现一个性质:这两个点都是红点间的路径上的,且最后的答案就是最大的红点间的间距的长度除以二上取整。

所以正解思路就为:找出最大的红点间的间距,再除以二向上取整。

暴力枚举复杂度为 O ( n 2 ) O(n^2) O(n2),显然不可行。

找到间距可以参考求树的直径的方法,两遍 D F S DFS DFS 即可。时间复杂度 O ( n ) O(n) O(n)

注意:当树上只有一个标记点时,答案为 0 0 0,要直接特判输出,不然会出问题(血淋淋的痛啊)。

AC Code

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int Maxn = 2e5 + 5;
int n, k, a[Maxn];
int vis[Maxn], f[Maxn], dis[Maxn];
vector<int> e[Maxn];
int ans;
inline void dfs1(int x, int fa);
inline void dfs2(int x, int fa);
inline void solve();
inline void work() {
	int T;
	cin >> T;
	while (T--)solve();
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	work();
	return 0;
}
inline void dfs1(int x, int fa) {
	if (fa != -1)f[x] = f[fa] + 1;
	for (auto i : e[x]) {
		if (i == fa)continue;
		dfs1(i, x);
	}
}
inline void dfs2(int x, int fa) {
	if (fa != -1)dis[x] = dis[fa] + 1;
	for (auto i : e[x]) {
		if (i == fa)continue;
		dfs2(i, x);
	}
}
inline void solve() {
	cin >> n >> k;
	for (int i = 1; i <= n; i++)e[i].clear(), dis[i] = f[i] = a[i] = 0;
	for (int i = 1; i <= k; i++)cin >> a[i];
	int u, v;
	for (int i = 1; i <= n - 1; i++)cin >> u >> v, e[u].push_back(v), e[v].push_back(u);
	if (k == 1) {
		cout << 0 << endl;
		return;
	}
	f[0] = -1, dis[0] = -1, dfs1(1, -1), ans = a[1];
	for (int i = 1; i <= k; i++)if (f[a[i]] > f[ans])ans = a[i];
	dfs2(ans, -1), ans = a[1];
	for (int i = 1; i <= k; i++)if (dis[a[i]] > dis[ans])ans = a[i];
	cout << (dis[ans] + 1) / 2 << endl;
}

洛谷评级: 普及 / 提高 − \textcolor{orange}{普及/提高−} 普及/提高,适合新手宝宝体质哦(颖音)。文章来源地址https://www.toymoban.com/news/detail-836961.html

到了这里,关于CF1881F Minimum Maximum Distance 题解 贪心+DFS的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【二分+贪心】CF1665 C

    Problem - C - Codeforces 题意:   思路: 一开始想太简单wa6了 只想到先感染大的分量,然后最后把最大的分量剩下的染色 但是可能会有别的分量更大(因为最后给最大的染色之后可能不再是最大的) 可以用堆维护,但是这里用二分做法 我们可以二分答案 mid ,问题就变成了 mid 秒

    2024年02月13日
    浏览(38)
  • CF786题解

    我不会告诉你链接在图片里 给出一个大小为 (n) 的环,点顺时针从 (1to n) 编号,两个人(设为 (0,1) )轮流移动其中的一个棋子。 对于第 (opt) 人,他能够将这个棋子顺时针移动 (xin S_{opt}) ( (S_{opt}) 是提前给出的)个步数,当某个人将棋子挪到 (1) 时这个人获胜。

    2024年02月05日
    浏览(41)
  • CF961E Tufurama 题解

      给定长度为 (n) 的序列 (a) ,统计二元组 ((i,j)) 的个数,使得该二元组满足 (1 leq i j leq n, a_i geq j, a_j geq i) 。 (n) 在 (2 times 10^{5}) 级别, (a_i) 在 (1 times 10^{9}) 级别。   我们考虑把序列中 (n) 个元素看成 ((i,a_i)) 坐标的点,至于平面直角坐标系中。我们先

    2024年02月08日
    浏览(47)
  • 洛谷 CF1743APassword 题解

    https://www.luogu.com.cn/problem/CF1743A 已知一个长度为四的,只包含字符 0 , 1 , 2 , … , 9 0,1,2,dots ,9 0 , 1 , 2 , … , 9 的字符串中不会出现哪些字符,求可能的字符串的数量。 Monocarp has forgotten the password to his mobile phone. The password consists of $ 4 $ digits from $ 0 $ to $ 9 $ (note that it can start wit

    2023年04月20日
    浏览(46)
  • CF1011A Stages 题解

    题目意思: 给你一个长度为 n n n 的字符串 a a a ,在这个字符串中选一个长度为 k k k 的好串(好串标准是啥自己去题目里看吧),问这个好串的最小价值是多少。 思路: 贪心。 首先我们将字符串 a a a 里面的字符进行排序。 因为要最小的价值,所以排好序后的 a a a 的第一个

    2024年02月12日
    浏览(30)
  • CodeForces CF1846G 题解

    CodeForces题目链接 洛谷题目链接 标准答案是状压之后,转化成Dijkstra算法跑最短路。我这里提供一个不一样的思路。 主人公得了病,有部分类型的症状。所有类型症状共有 (n) 种,用长为 (n) 的01串表示是否有那种症状。共有 (m) 种药,吃第 (i) 种药需要花费时间 (t_i) ,

    2024年02月14日
    浏览(39)
  • CF1145G AI Takeover 题解

    人工智能取得了进展。在这一题中,我们考虑的是石头剪刀布游戏。 然而,比赛的前一天晚上有一群人把机器人弄坏了,于是使用一个程序替代。 您需要找到一个策略,使您能够获胜。祝你好运! 为了方便,石头剪刀布分别用三个字符表示: R , P , S 。 本题有 6 个测试点,

    2024年03月26日
    浏览(43)
  • CF338D GCD Table 题解

    你有一个长度为 (k) 的数列 (a) , 询问是否存在 (xin[1,n]~~~yin[1,m]) 使得 (forall i~~~ gcd(x,y+i-1)=a_i) 。 我们转换一下可以得到: [forall i ~~left{ begin{matrix}xequiv 0pmod{a_i} \\\\y+i-1equiv 0pmod{a_i}end{matrix}right.] 前面一个 (x) 很好解决,直接 最大公倍数 。 (y) 可以转化一下:

    2024年02月07日
    浏览(37)
  • LeetCode 1921. Eliminate Maximum Number of Monsters【贪心,计数排序】1527

    本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章中,我不仅会讲解多种解题思路及其优化,

    2024年02月09日
    浏览(51)
  • 贪心找性质+dp表示+矩阵表示+线段树维护:CF573D

    比较套路的题目 首先肯定贪心一波,两个都排序后尽量相连。我一开始猜最多跨1,但其实最多跨2,考虑3个人的情况: 我们发现第3个人没了,所以可以出现跨2的情况 然后直接上dp,由 i − 1 , i − 2 , i − 3 i-1,i-2,i-3 i − 1 , i − 2 , i − 3 转移过来。 然后这显然可以拿矩阵表

    2024年02月07日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包