#P13782. [eJOI 2022] Where Is the Root?
[eJOI 2022] Where Is the Root?
Description
给定一棵包含 个顶点的树。树是一种图,保证任意两个顶点之间恰好存在一条简单路径。同时保证至少有一个顶点与不少于 3 个顶点直接相连。 其中有一个顶点是根节点,你的任务是找出它。为此,你可以进行如下形式的询问:
- 给定一个顶点集合 ,检查它们的最近公共祖先是否在这个集合中。
对于顶点集合 ,若顶点 位于从 中所有顶点到根的路径上,则称 为 的公共祖先。集合 的最近公共祖先(LCA)是指离根最远的那个公共祖先。
交互说明
交互开始时,首先读入一个整数 (),表示顶点数量。
接着读入 行,每行包含两个整数 (),表示在顶点 和 之间有一条边。
保证输入的 条边构成一棵树,并且至少有一个顶点的度数不小于 3。
你可以通过如下方式发起询问:先输出 "?",再输出一个整数 ,然后输出 个互不相同的整数 (),表示你想要检查的顶点集合。
交互器会返回 "YES",如果它们的 LCA 属于集合 ;否则返回 "NO"。
你最多可以询问 1000 次,但分数将取决于你的询问次数。输出最终答案不计入询问次数。请参考评分部分获取详细说明。
当你确认根节点后,输出符号 "!",然后输出一个整数 (),表示根节点。然后终止程序。
在输出每次询问后,不要忘记输出换行并刷新缓冲区。可以使用:
- 在 C++ 中使用
fflush(stdout)或cout.flush(); - 在 Python 中使用
stdout.flush()。
保证对于每个测试用例,树和其根节点在交互开始前已经固定,交互器不会自适应改变。
7
4 1
1 2
4 3
3 5
3 6
4 7
NO
YES
NO
YES
? 2 5 6
? 3 6 3 5
? 2 1 7
? 2 4 6
! 4
Hint
样例说明

第一次询问:顶点 和 的 LCA 是顶点 ,不在集合 中,因此返回 "NO"。
第二次询问:顶点 的 LCA 是顶点 ,在集合中,因此返回 "YES"。
第三次询问:顶点 和 的 LCA 是顶点 ,不在集合中,因此返回 "NO"。
第四次询问:顶点 和 的 LCA 是顶点 ,在集合中,因此返回 "YES"。
由此可以推测根节点是顶点 ,这就是正确答案。
评分规则
- (7 分):
- (10 分):
- (最高 83 分):
在前两个子任务中,你最多可以询问 1000 次。
在第三个子任务中,设 为你在某个测试用例中使用的最大询问次数:
- 如果 ,你将得到 83 分。
- 否则,你将得到:$$\left\lfloor \max \left(10,\ 83 \cdot \left(1 - \frac{\ln(k - 6)}{7}\right)\right) \right\rfloor$$
以下是 C++ 代码实现的计分函数:
((k <= 9) ? 83 : max(10, int(83 * (1 - log(k - 6.0) / 7))))
翻译由 ChatGPT-5 完成
京公网安备 11011102002149号