标签: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