树的直径(Diameter)是指树上的最长简单路。
直径的求法:两遍BFS (or DFS)
任选一点u为起点,对树进行BFS遍历,找出离u最远的点v
以v为起点,再进行BFS遍历,找出离v最远的点w。则v到w的路径长度即为树的直径
http://acm.hdu.edu.cn/showproblem.php?pid=4607
#include<string.h>
#include<stdio.h>
#include<queue>
#define Max(a,b) a>b?a:b
using namespace std;
int head[100010],vis[100010],dis[100010],cnt;
struct Node
{
int to,next;
}Edge[200010];
void addEdge(int u,int v)
{
Edge[cnt].to=v;
Edge[cnt].next=head[u];
head[u]=cnt++;
}
void DFS(int u)
{
for(int i=head[u];~i;i=Edge[i].next)
{
if(vis[Edge[i].to]==0)
{
vis[Edge[i].to]=1;
dis[Edge[i].to]=dis[u]+1;
DFS(Edge[i].to);
}
}
}
int main(){
int t,n,m,k,a,b;
scanf("%d",&t);
while(t--)
{
scanf("%d%d", &n, &m);
memset(dis,0,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(head,-1,sizeof(head));
cnt=0;
for(int i=1;i<n;i++)
{
scanf("%d%d",&a,&b);
addEdge(a,b);
addEdge(b,a);
}
vis[1]=1;
DFS(1);
int pos,len=0;
for(int i=1;i<=n;i++)
{
if(len<dis[i])
{
pos=i;
len=dis[i];
}
}
memset(dis,0,sizeof(dis));
memset(vis,0,sizeof(vis));
vis[pos]=1;
DFS(pos);
len=0;
for(int i=1;i<=n;i++)
{
len=Max(len,dis[i]);
}
len++;
for(int i=0;i<m;i++)
{
scanf("%d",&k);
if(k<=len)
{
printf("%d\n",k-1);
}
else
{
printf("%d\n",len-1+(k-len)*2);
}
}
}
return 0;
}