hdu 4607(树的直径)

Posted C-DmLy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 4607(树的直径)相关的知识,希望对你有一定的参考价值。

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

 

题解:给定一棵树,从树中的任意选一个顶点出发,遍历K个点的最短距离是多少?(每条边的长度为1)

 

算法分析:

首先如果k小于等于直径长度,那么答案为k−1;
如果k大于直径长度,设直径长度为r,那么答案为r−1+(k−r)*2;
树的直径:树上的最长简单路径;

 

代码:

  1 #include <cstdio>
  2 #include <cmath>
  3 #include <cstring>
  4 #include <string>
  5 #include <algorithm>
  6 #include <queue>
  7 #include <stack>
  8 #include <map>
  9 #include <set>
 10 #include <vector>
 11 #include <iostream>
 12 using namespace std;
 13 #define for0(i, n) for(int i=0; i<(n); ++i)
 14 #define for1(i,a,n) for(int i=(a);i<=(n);++i)
 15 #define for2(i,a,n) for(int i=(a);i<(n);++i)
 16 #define for3(i,a,n) for(int i=(a);i>=(n);--i)
 17 #define for4(i,a,n) for(int i=(a);i>(n);--i)
 18 #define CC(i,a) memset(i,a,sizeof(i))
 19 #define LL long long
 20 #define MOD 1000000007
 21 #define INF 0x3f3f3f3f
 22 #define PI 3.1415926
 23 #define N 300005
 24 
 25 int vis[N],head[N];
 26 int n,maxx,k;
 27 
 28 struct node 
 29 {
 30     int x,y;
 31     int next;
 32 }a[N];
 33 
 34 void dfs(int x,int len,int vis[])
 35 {
 36     if(len>maxx){
 37         maxx=len;
 38         k=x;
 39     }
 40     for(int i=head[x]; i!=-1; i=a[i].next){
 41         if(!vis[a[i].y]){
 42             vis[a[i].y]=1;
 43             dfs(a[i].y,len+1,vis);
 44             vis[a[i].y]=0;
 45         }
 46     }
 47 }
 48 
 49 void init()
 50 {
 51     for(int i=1; i<=n; i++){
 52         vis[i]=0;
 53         head[i]=-1;
 54     }
 55 }
 56 
 57 void get()
 58 {
 59     int u,v,l=1;
 60     for(int i=1; i<n; i++){
 61         scanf("%d%d",&u,&v);
 62         a[l].x=u;
 63         a[l].y=v;
 64         a[l].next=head[u];
 65         head[u]=l++;
 66 
 67         a[l].x=v;
 68         a[l].y=u;
 69         a[l].next=head[v];
 70         head[v]=l++;
 71     }
 72 }
 73 
 74 int main()
 75 {
 76     int t,m;
 77     scanf("%d",&t);
 78     while(t--){
 79         scanf("%d%d",&n,&m);
 80         init();
 81         get();
 82 
 83         maxx=-1;
 84         vis[1]=1;
 85         dfs(1,0,vis);
 86         for (int i=1; i<=n; i++)
 87             vis[i]=0;  
 88         vis[k]=1;
 89         dfs(k,0,vis);
 90         for (int i=0; i<m; i++)  
 91         {  
 92             scanf("%d",&k);  
 93             if(k<=maxx+1)  
 94             {  
 95                 printf("%d\n",k-1);  
 96             }  
 97             else  
 98             {  
 99                 printf("%d\n",maxx+(k-maxx-1)*2);  
100             }  
101         }  
102     }
103     return 0;
104 }

 

以上是关于hdu 4607(树的直径)的主要内容,如果未能解决你的问题,请参考以下文章

HDU - 4607 Park Visit (树的直径)

求树的直径+并查集(bfs,dfs都可以)hdu4514

hdu 2196 Computer 树的直径

HDU 4612 Warm up(双连通分量缩点+求树的直径)

hdu 4514(树的直径+并查集)

HDU4612:Warm up(缩点+树的直径)