求出树的直径d。当k<=d的时候,显然直接在直径上走就行了,当k>d的时候,便是直径d的长度 加上 多出来的点数*2.
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cstring>
#define FF(i, a ,b) for(int i=a; i<b; i++)
#define FD(i, a ,b) for(int i=a; i>b; i--)
#define REP(i, n) for(int i=0; i<n; i++)
#define LL long long
#define CLR(a, b) memset(a, b, sizeof(a))
#define PB push_back
using namespace std;
const int maxn = 111111;
int n, m, dist, k, end;
vector<int> G[maxn];
void dfs(int x, int fa, int d)
{
int nc = G[x].size();
if(nc == 1)
{
if(d > dist)
{
dist = d;
end = x;
}
}
REP(i, nc)
{
int v = G[x][i];
if(v != fa)
{
dfs(v, x, d+1);
}
}
}
int main()
{
int T, a, b;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m);
REP(i, n+1) G[i].clear();
FF(i, 1, n)
{
scanf("%d%d", &a, &b);
G[a].PB(b);
G[b].PB(a);
}
dist = 0;
dfs(1, -1, 0);
dfs(end, -1, 0);
dist++;
while(m--)
{
scanf("%d", &k);
if(k <= dist) printf("%d\n", k-1);
else printf("%d\n", dist - 1 + (k-dist)*2);
}
}
return 0;
}