题目链接: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 ",k-1); 96 } 97 else 98 { 99 printf("%d ",maxx+(k-maxx-1)*2); 100 } 101 } 102 } 103 return 0; 104 }