//给一棵双向树,数中边的权值为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 ;
}
相关文章
- 51 nod 1427 文明 (并查集 + 树的直径)
- codeforces 690C2 C2. Brain Network (medium)(bfs+树的直径)
- poj--2631--Roads in the North(树的直径 裸模板)
- POJ 2631 Roads in the North (树的直径)
- HDU 2196.Computer 树形dp 树的直径
- 2017湘潭大学邀请赛H题(树的直径)
- [10.12模拟赛] 老大 (二分/树的直径/树形dp)
- codeforces gym-101755 I-Guess the Tree 交互题、分治、树的直径
- [LeetCode] Diameter of Binary Tree 二叉树的直径
- CodeForces 455C Civilization (并查集+树的直径)