题意:
给出
n
n
n 个点,
n
−
1
n-1
n−1 条边,最多询问
n
2
\frac{n}{2}
2n 次,每次询问
u
,
v
u,v
u,v,会给出
u
v
uv
uv的最近公共祖先,求树的根。
这个道题单独来看是不难,变成交互题就难了,对于交互题不理解的可以参考这篇博客:点击这里
操作就是一个删除叶子节点的过程。
AC代码:
const int N = 1010;
int n;
int u, v, x;
set<int> g[N];
int ans[N];
int main()
{
sd(n);
rep(i, 1, n - 1)
{
sdd(u, v);
g[u].insert(v);
g[v].insert(u);
}
while (1)
{
ans[0] = 0;
rep(i, 1, n)
{
if (g[i].size() == 1)
ans[++ans[0]] = i;
}
printf("? %d %d\n", ans[1], ans[2]);
fflush(stdout);
sd(x);
if (x == ans[1] || x == ans[2])
{
printf("! %d\n", x);
return 0;
}
g[*g[ans[1]].begin()].erase(ans[1]);
g[ans[1]].clear();
g[*g[ans[2]].begin()].erase(ans[2]);
g[ans[2]].clear();
if (g[x].empty())
{
printf("! %d\n", x);
return 0;
}
}
return 0;
}