「ALFR Round 5」D 游戏 题解
验题人题解。
题目链接
「ALFR Round 5」D 游戏
解题思路
考虑交互库做这两种操作我们分别能得到什么信息。
如果交互库执行向
如果交互库告诉你当前
首先特判
我们考虑持续询问一个可能为关键点
因此如果交互库在做操作一时,此时可以直接删除树上非
注意到
参考代码
ll n,m;
ll x,y;
vector<ll>G[1000010];
ll in[1000010];
ll vis[1000010];
set<ll>v,v2;
ll S;
ll ask(ll x)
{
cout<<"? "<<x<<endl;
ll y;
cin>>y;
if(y==1)
return -1;
return rd();
}
void _clear(){}
void solve()
{
_clear();
cin>>n>>m;
S=n;
v.clear();
forl(i,1,n)
in[i]=0,
vis[i]=0,
G[i].clear();
forl(i,2,n)
cin>>x>>y,
G[x].pb(y),
G[y].pb(x),
in[x]++,in[y]++;
forl(i,1,n)
if(in[i]==1)
v.insert(i),
vis[i]=1,
S--;
if(v.size()<1)
{
cout<<"! 1"<<endl;
rd();
return ;
}
while(v.size()>1)
{
ll now=*v.begin();
ll num=ask(now);
if(num==-1)
{
set<ll>v2;
v2.insert(now);
for(auto i:v)
if(i!=now)
for(auto j:G[i])
{
in[j]--;
if(in[j]==1 && !vis[j])
v2.insert(j),
S--,
vis[j]=1;
}
v=v2;
}
else
{
if(num==0)
{
v.clear();
cout<<"! "<<now<<endl;
if(!rd())
exit(-1);
return ;
}
v.erase(now);
for(auto j:G[now])
{
in[j]--;
if(in[j]==1 && !vis[j])
v.insert(j),
S--,
vis[j]=1;
}
}
}
if(v.size()==0)
exit(0);
cout<<"! "<<*v.begin()<<endl;
v.clear();
if(!rd())
exit(-1);
}