Description

图片说明

Solution

可以把题目转化成求 1-n 里到点集S的最远距离最小的结果,而这个点应该出现在点集S中离得最远的两个点连线的中点上。
而点集S的最远距离就是求直径,直接dfs的复杂度是 的,但是我们可以通过处理出LCA,先找到深度最大的点作为直径的一端,另一端通过枚举得到。设直径的长度为 ,最终结果就是ceil().

Code

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
const int mod = 1e9 + 7; 
const int N = 5e5 + 5;
struct node {
  int to, nextz;
}edge[N << 1];
int tot, head[N];
void addedge(int u, int v) {
  edge[tot].to = v;
  edge[tot].nextz = head[u];
  head[u] = tot++;
}
void init() {
  memset(head, -1, sizeof(head));
  tot = 0;
}
int fa[N][40];
int deg[N];
void bfs(int root) {
  fa[root][0] = root;
  deg[root] = 0;
  queue<int> q; q.push(root);
  while(!q.empty()) {
    int tmp = q.front(); q.pop();
    for(int i = 1; i < 35; i++) {
      fa[tmp][i] = fa[fa[tmp][i - 1]][i - 1];
    }
    for(int i = head[tmp]; ~i; i = edge[i].nextz) {
      int v = edge[i].to;
      if(v == fa[tmp][0]) continue;
      q.push(v); deg[v] = deg[tmp] + 1; fa[v][0] = tmp;
    }
  }
}
int LCA(int u, int v) {
  if(deg[u] > deg[v]) swap(u, v);
  int hu = deg[u], hv = deg[v];
  int tu = u, tv = v;
  for(int det = hv - hu, i = 0; det; det >>= 1, i++) {
    if(det & 1) tv = fa[tv][i];
  }
  if(tu == tv) return tu;
  for(int i = 34; i >= 0; i--) {
    if(fa[tu][i] == fa[tv][i]) continue;
    tu = fa[tu][i], tv = fa[tv][i];
  }
  return fa[tu][0];
}
int cal(int x, int y) {
  return deg[x] + deg[y] - 2 * deg[LCA(x, y)];
}
int main() {
  ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  init();
  int n, m; cin >> n;
  for(int i = 1; i <= n - 1; i++) {
    int x, y; cin >> x >> y; addedge(x, y); addedge(y, x);
  }
  bfs(1);
  cin >> m;
  while(m--) {
    vector<int> v;
    int num, x; cin >> num;
    int maxz = 0, u = 0;
    for(int i = 1; i <= num; i++) {
      cin >> x, v.push_back(x);
      //cout << x << ' ' << deg[x] << "\n";
      if(deg[x] > maxz) {
        maxz = deg[x];
        u = x;
      }
    }
    maxz = 0;
    for(auto x : v) {
      maxz = max(maxz, cal(u, x));
    }
    cout << (maxz + 1) / 2 << "\n";
  }
  return 0;
}