给定一棵树
需要每次询问两个点
然后读取这两个点的lca
问这棵树的根节点是?
最多n/2次查询
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
struct node
{
int to,next;
}q[20005];
int head[20005],cnt=1;
int e[2000];
void add(int x,int y)
{
q[cnt].to=y;
q[cnt].next=head[x];
head[x]=cnt++;
}
int main()
{
memset(head,-1,sizeof(head));
int n,a,b;
cin>>n;
for(int i=1;i<=n-1;i++)
{
cin>>a>>b;
add(a,b);add(b,a);
e[a]++;e[b]++;
}
stack<int> st;
for(int i=1;i<=n;i++)
{
if(e[i]==1)
{
st.push(i);}
}
//int ex=(n%2==0)?0:1;
for(int i=1;i<=n/2;i++)
{
int f;
int u=st.top();st.pop();
int v=st.top();st.pop();
cout<<"? "<<u<<" "<<v<<endl;
fflush(stdout);
cin>>f;
if(f==u||f==v)
{
cout<<"! "<<f<<endl;break;}
if(n%2!=0)
{
if(i==n/2)
{
for(int i=1;i<=n;i++)
{
if(e[i]>1)
{
cout<<"! "<<i<<endl;break;}
}
break;
}
}
for(int i=head[u];i!=-1;i=q[i].next)
{
e[q[i].to]--;
if(e[q[i].to]==1)
{
st.push(q[i].to);}
}
for(int i=head[v];i!=-1;i=q[i].next)
{
e[q[i].to]--;
if(e[q[i].to]==1)
{
st.push(q[i].to);}
}
}
return 0;
}