标签:des style color java os io strong for
1 4 2 3 2 1 2 4 2 2 4
1 4
树的直径(Diameter)是指树上的最长简单路。
直径的求法:两遍BFS (or DFS)
任选一点u为起点,对树进行BFS遍历,找出离u最远的点v
以v为起点,再进行BFS遍历,找出离v最远的点w。则v到w的路径长度即为树的直径
求树的直径,任选一个点,从该点开始广搜,最后一个入队的一定是树直径的一端;然后在从这一点开始,再次广搜,则能得到树的直径。然后可以发现,当K小于等于直径Len时,长度为k-1;否则,长度为(k-len)*2+len-1.
#include"stdio.h"
#include"string.h"
#include"queue"
#include"algorithm"
using namespace std;
#define N 100005
struct node
{
int u,v,next;
}e[N*2];
int a[N];
int head[N],t,len;
bool mark[N];
void add(int u,int v)
{
e[t].u=u;
e[t].v=v;
e[t].next=head[u];
head[u]=t++;
}
int bfs(int s)
{
int i,u,v;
queue<int>q;
q.push(s);
memset(mark,false,sizeof(mark));
mark[s]=true;
while(!q.empty())
{
u=q.front();
q.pop();
for(i=head[u];i!=-1;i=e[i].next)
{
v=e[i].v;
if(!mark[v])
{
mark[v]=true;
q.push(v);
}
}
}
return u;
}
void bfs_len(int s)
{
int i,v;
queue<int>q;
q.push(s);
memset(mark,false,sizeof(mark));
mark[s]=true;
memset(a,0,sizeof(a));
while(!q.empty())
{
s=q.front();
q.pop();
len=len>a[s]?len:a[s];
for(i=head[s];i!=-1;i=e[i].next)
{
v=e[i].v;
if(!mark[v])
{
mark[v]=true;
a[v]=a[s]+1;
q.push(v);
}
}
}
return ;
}
int main()
{
int T,i,u,v,k,n,m;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
t=0;
memset(head,-1,sizeof(head));
for(i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
len=0;
u=bfs(1);
bfs_len(u);
len++;
while(m--)
{
scanf("%d",&k);
if(k<=len)
printf("%d\n",k-1);
else
printf("%d\n",(k-len)*2+len-1);
}
}
return 0;
}hdu 4607 Park Visit (树的直径),布布扣,bubuko.com
标签:des style color java os io strong for
原文地址:http://blog.csdn.net/u011721440/article/details/38468825