问题转化为找s集合中距离最远的两点的距离
#include <bits/stdc++.h>
using namespace std;
const int maxn=3e5+10;
int n,m,he[maxn];
int read(){
int x; scanf("%d",&x);
return x;
}
struct edge{
int to,nxt;
}d[maxn<<1]; int head[maxn<<1],cnt=1;
void add(int u,int v){
d[++cnt]=(edge){v,head[u]},head[u]=cnt;
}
int deep[maxn],fa[maxn][22],lg[maxn];
void dfs(int u,int father)
{
deep[u]=deep[father]+1;
fa[u][0]=father;
for(int i=1;i<=lg[ deep[u] ];i++)
fa[u][i]=fa[ fa[u][i-1] ][i-1];
for(int i=head[u];i;i=d[i].nxt )
{
int v=d[i].to;
if( v==father ) continue;
dfs(v,u);
}
}
int lca(int x,int y)
{
if( deep[x]<deep[y] ) swap(x,y);
while( deep[x]>deep[y] )
x=fa[x][ lg[deep[x]-deep[y]]-1 ];
if( x==y ) return x;
for(int i=lg[ deep[x] ]-1;i>=0;i-- )
if( fa[x][i]!=fa[y][i] )
x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
void init()
{
for(int i=1;i<=n;i++)
lg[i]=lg[i-1]+( (1<<lg[i-1])==i );
}
int main()
{
n=read();
init();
for(int i=1;i<n;i++)
{
int l,r;
l=read(),r=read();
add(l,r); add(r,l);
}
dfs(1,0);
int q; q=read();
while( q-- )
{
int s=read();
int shen=0,num=0,ans=0;
for(int i=1;i<=s;i++)
{
he[i]=read();
if( deep[ he[i] ]>shen )
shen=deep[ he[i] ],num=he[i];
}
for(int i=1;i<=s;i++)
{
if( he[i]==num ) continue;
int zu=lca(num,he[i] );
int juli=deep[num]+deep[ he[i] ]-2*deep[zu];
ans=max(ans,juli);
}
printf("%d\n",(ans+1)/2);
}
}
京公网安备 11010502036488号