地址:https://codeforces.com/contest/1174/problem/F
思路:思维+分治
官方题解:https://codeforces.com/blog/entry/67388
Code:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
using namespace std;
typedef long long LL;
typedef pair<int,int> pr;
const int MAX_N=2e5+5;
int n,ans;
vector<int> e[MAX_N];
int sz[MAX_N],dis[MAX_N];
int d[MAX_N],Pre[MAX_N],dx;
void DFS(int u,int pre);
void Find(int u);
int get(int u,int pre,int v1,int si);
int main()
{
scanf("%d",&n);
int u,v;
for(int i=1;i<n;++i)
{
scanf("%d%d",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
DFS(1,0);
printf("d 1\n");
fflush(stdout);
scanf("%d",&dx);
Find(1);
cout<<"! "<<ans<<endl;
return 0;
}
void DFS(int u,int pre)
{
sz[u]=1; d[u]=u; Pre[u]=pre;
int Max=0;
for(auto v:e[u])
if(v!=pre){
dis[v]=dis[u]+1;
DFS(v,u);
sz[u]+=sz[v];
if(d[u]==u||Max<sz[v]){
Max=sz[v]; d[u]=d[v];
}
}
}
void Find(int u)
{
if(dis[u]==dx){
ans=u; return;
}
int v=d[u],dv,dxv;
printf("d %d\n",v);
fflush(stdout);
scanf("%d",&dxv);
int vi,ds=(dx+dis[v]-dxv)/2;
vi=get(u,Pre[u],d[u],ds-dis[u]);
if(ds==dx){
ans=vi;
}else{
printf("s %d\n",vi);
fflush(stdout);
scanf("%d",&vi);
Find(vi);
}
}
int get(int u,int pre,int v1,int si)
{
if(!si) return u;
int res;
for(auto v:e[u])
if(v!=pre&&d[v]==v1){
res=get(v,u,v1,si-1);
break;
}
return res;
}