//给一棵双向树,数中边的权值为1,问对于这颗树中走k个节点的最短路径
//如果k小于这颗数的直径加1,那么走k个节点就没有重复的路,如果大于
//那么大于的节点都需要走两遍
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std ;
const int maxn = 100010 ;
int head[maxn] ;
int vis[maxn] ;
struct Edge
{
int v ;
int next ;
}edge[maxn*2] ;
int nedge ;
void addedge(int u , int v)
{
edge[nedge].v = v ;
edge[nedge].next = head[u] ;
head[u] = nedge++ ;
edge[nedge].v = u ;
edge[nedge].next = head[v] ;
head[v] = nedge++ ;
}
queue<int>que ;
int ma = 0 ;
int bfs(int st)
{
while(que.size())que.pop() ;
que.push(st) ;que.push(0) ;que.push(0) ;
int pos ;
while(que.size())
{
int u = que.front() ; que.pop() ;
int step = que.front() ;que.pop() ;
int pre = que.front() ; que.pop() ;
if(step > ma)
{
ma = step ;
pos = u ;
}
for(int i = head[u] ; i != -1 ;i = edge[i].next)
{
int v = edge[i].v ;
if(v == pre)continue ;
que.push(v);que.push(step+1);que.push(u) ;
}
}
return pos ;
}
int main()
{
int t ;
scanf("%d" , &t) ;
while(t--)
{
int n , m ;
memset(head , -1 ,sizeof(head)) ;
nedge = 0 ;
scanf("%d%d" , &n , &m) ;
for(int i = 1;i < n; i++)
{
int u ,v ;
scanf("%d%d" , &u , &v) ;
addedge(u , v) ;
}
ma = 0 ;
int pos = bfs(1) ;
bfs(pos) ;
while(m--)
{
int k ;
scanf("%d" , &k) ;
if(k <= ma+1)printf("%d\n" , k - 1) ;
else printf("%d\n" , (k - (ma+1))*2+ma) ;
}
}
return 0 ;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。