hdu 4607 Park Visit 求树的直径

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607

题目大意:给你n个点,n-1条边,将图连成一棵生成树,问你从任意点为起点,走k(k<=n)个点,至少需要走多少距离(每条边的距离是1);

思路:树形dp求树的直径r;

                a:若k<=r+1 ,ans = k-1;

                b:若k>=r+1,ans = r+(k-(r+1))*2;

代码:

 1 #include "stdio.h"
 2 #include "string.h"
 3 
 4 #define N 110000
 5 
 6 struct node
 7 {
 8     int x,y;
 9     bool visit;
10     int next;
11 } edge[2*N];
12 int idx,head[N];
13 
14 inline int MAX(int a,int b)
15 {
16     return a>b?a:b;
17 }
18 void Init()
19 {
20     idx=0;
21     memset(head,-1,sizeof(head));
22 }
23 void Add(int x,int y)
24 {
25     edge[idx].x=x;
26     edge[idx].y=y;
27     edge[idx].visit=false;
28     edge[idx].next=head[x];
29     head[x]=idx++;
30 }
31 
32 int n;
33 int maxn[N],smaxn[N];
34 
35 void DFS(int x)
36 {
37     int i,y;
38     maxn[x] = smaxn[x] = 0;
39     for(i=head[x]; i!=-1; i=edge[i].next)
40     {
41         y = edge[i].y;
42         if(edge[i].visit) continue;
43         edge[i].visit = edge[i^1].visit = true;
44         DFS(y);
45         if(maxn[y]+1>maxn[x])
46         {
47             smaxn[x] = maxn[x];
48             maxn[x] = maxn[y]+1;
49         }
50         else if(maxn[y]+1>smaxn[x])
51             smaxn[x] = maxn[y]+1;
52     }
53 }
54 
55 int main()
56 {
57     int T,Q;
58     int i,j;
59     int x,y,k;
60     scanf("%d",&T);
61     while(T--)
62     {
63         Init();
64         scanf("%d%d",&n,&Q);
65         for(i=1; i<n; ++i)
66         {
67             scanf("%d %d",&x,&y);
68             Add(x,y);
69             Add(y,x);
70         }
71         DFS(1);
72         int D=0;  //树的直径
73         for(i=1; i<=n; ++i)
74             D = MAX(D,maxn[i]+smaxn[i]);
75         D++;
76         while(Q--)
77         {
78             scanf("%d",&k);
79             if(k<=D)
80                 printf("%d\n",k-1);
81             else
82                 printf("%d\n",D-1+(k-D)*2);
83         }
84     }
85     return 0;
86 }

 





 

posted @ 2014-05-06 11:09  ruo_yu  阅读(339)  评论(0编辑  收藏  举报