6916. 【2020.12.02提高组模拟】牧羊人(shepherd)

该博客讨论了一种树形结构中安排牧羊人保护羊的策略,确保每只羊都被至少一个牧羊人保护。通过预处理每个节点到最近羊的距离,采用贪心算法,每次选择深度最深的节点并向上找到最近的能够覆盖它的点来放置牧羊人。算法以O(n)的时间复杂度实现,提供了具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

 一棵树上有 K 只羊,树是一个没有环的简单连通图。这棵树有 N 个节点,用 1 到 N表示。树的每个节点最多只能住一只羊。Soaring 意识到,狼迟早会学会爬树。为了保护羊,Soaring 决定安排一些牧羊人住在在树中某些节点上,以确保每只羊至少被一个牧羊人保护。众所周知,每个牧羊人都会保护所有离他最近的羊,且只会保护它们。羊和牧羊人的距离等于两者之间简单路径的边数包含绵羊的节点和包含shepherd 的节点之间一路径上的节点。此外,牧羊人可以跟羊住在一起,当然,这种情况下,牧羊人只保护这只羊。计算最少需要放置多少个牧羊人,使得每只羊都至少被一个牧羊人保护。另外,输出一种放置方案。

Input

输入文件名为 shepherd.in。
第一行两个整数 N 和 K(1<=K<=N)
接下来 N-1 行,每行包含两个整数 a i 和 b i (1≤ai,bi≤N),描述树中的边。
接下来一行包含 K 个不同的整数 O i (1≤O i ≤N),表示 K 只羊居住的节点编号。

Output

输出文件名为 shepherd.out。
第一行输出一个数字 X,表示最小需要的牧羊人数。
第二行输出 X 个空格分隔的整数, 表示牧羊人居住的节点编号。
如果有多个方案,输出其中任何一个。

Sample Input

input1:

4 2
1 2
2 3
3 4
1 4

input2:

9 5
1 2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值