Logo Universal Online Judge

UOJ

时间限制:4 s 空间限制:512 MB
统计

题目描述

这是一道交互题。

你本来是要去下界堡垒参加猪灵的黄金派对的,但很不幸的是,你迷路了。你现在既不知道自己在哪,也不知道自己要去的下界堡垒在哪。

下界的地形构成了一棵由 $n$ 个点组成的树(树上的点编号为 $1$ 到 $n$)的结构,你现在的位置在点 $a$,你想去的地方为点 $b$。你已经知道了树的结构,但是不知道 $a,b$ 的值。好消息是,你的猪灵朋友将会帮助你找出它们。

首先,你的猪灵朋友会告诉你 $a,b$ 之间的路径上的一个点 $c$。然后你可以进行若干次操作,具体而言,你可以要求他把磁石移动到点 $u$,然后你通过观察指南针就可以知道

  • 如果把点 $u$ 看做树的根,那么 $a,b$ 在树上的最近公共祖先是哪个点。

但是,你的猪灵朋友在告诉你 $c$ 之前,想要先知道根据该树形态和你的策略,最坏情况下至少需要搬动磁石的次数 $e$。当然,在你告诉他 $e$ 之后,他就只允许你进行 $e$ 次操作了。

交互方式

你不需要,也不应该实现主函数,你只需要实现函数 void solve(int n, const std::vector<std::pair<int, int>> &E),这里的 $n$ 表示树所包含的点数,$E$ 给出了树上有连边的点对,保证 $E$ 的长度为 $n-1$。你可以通过调用如下三个函数来和交互库进行交互:

  • int set_limit(int e):回答最坏情况下至少需要搬动磁石的次数 ,这个函数必须在其他函数之前调用,并且被调用恰好一次。这个函数返回 $a,b$ 之间的路径上的一个点 $c$;

  • int query(int u):要求猪灵朋友把磁石移动到点 $u$,返回在树上把点 $u$ 看做树的根时,$a,b$ 在树上的最近公共祖先;

  • void answer(int a, int b):回答你的位置和下界堡垒的位置 ,这个函数必须被最后调用,且被调用恰好一次。

约束

  • 对于 $20\%$ 的数据,有 $1\le n\le4$;

  • 对于另外 $30\%$ 的数据,有 $1\le n\le2000$;

  • 对于全部数据,有 $1\le n\le10^5$。

题目保证:

  • 一定有 $a\le b$;

  • 给出的边一定构成一颗树;

  • 评测时,交互库会恰好调用 solve 一次;

  • 本题保证所选定的点 $a,b,c$ 在交互开始之前已经完全确定,不会根据和你的程序的交互过程动态构造,因此题目中的交互操作都是确定性的,你不需要关心这些操作在交互库中的具体实现;

  • 在保证询问次数不超过 $n$ 的前提下,交互库所使用的的时间不超过 2 秒,空间不超过 128MiB,也就是说你至少有 2 秒时间和 384MiB 空间可以使用。

你要保证:

  • 在调用 set_limit 函数之前不会调用 queryanswer 函数,且传入的参数 $e$ 满足 $0\le e\le n$;

  • 调用 query 函数的次数不超过你在调用 set_limit 函数时传入的参数 $e$,且传入的参数 $u$ 满足 $1\le u\le n$;

  • 调用 answer 之后从 solve 函数中立即返回。

评分标准

在答案正确的前提下,若按照你的策略,最坏情况下至少需要搬动磁石的次数为 $e$。按照最优策略,最坏情况下至少需要搬动磁石的次数为 $e'$。令 $\alpha=(e+1)/(e'+1)$,那么:

  • 若 $\alpha<1$,得 $0\%$ 的分数;

  • 若 $\alpha=1$,得 $100\%$ 的分数;

  • 若 $1<\alpha\le1.1$,得 $20\%$ 的分数;

  • 若 $\alpha>1.1$,得 $10\%$ 的分数。

实现细节

下发文件已经提供了一个 sample.cpp ,你可以将这个文件拷贝一份,重命名为 compass.cpp,然后在其基础上答题。

请确保你的程序开头包含:

#include "compass.h"

试题目录下的 grader.cpp 以及 compass.h 是我们提供的交互库参考实现,最终测试时所用的交互库实现与该参考实现有所不同,因此选手的解法不应该依赖交互库实现。

你需要在本题目录下使用如下命令编译得到可执行程序:

g++ grader.cpp compass.cpp -o compass -O2 -std=c++14

对于编译得到的可执行程序,可执行文件将从标准输入读入以下格式的数据:

第一行一个整数 $n$,然后 $n-1$ 行描述树的结构。最后一行三个数 $a,b,c$。读入完成之后,交互库将调用恰好一次函数 solve,用输入的数据测试你的函数。你的函数正确返回后,交互库会判断你的计算是否正确,若正确则会输出 OK. 和交互函数调用次数相关信息,否则会输出相应的错误信息。

提示

不保证 $a\not=b$,$a\not=c$,或 $b\not=c$。

下发文件及样例