题目:
Park Visit
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607
分析:求树的直径。所谓树的直径,指的是一棵树里任意两点之间的最远距离。方法为选定一点,然后从该点bfs,则最后一个出栈的点必为直径的一端,然后以该点为起点bfs,求出直径即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<vector> 7 #include<queue> 8 using namespace std; 9 #define maxn 100005 10 int T,n,m; 11 vector<int>g[maxn]; 12 bool vis[maxn]; 13 int bfs() 14 { 15 memset(vis,false,sizeof(vis)); 16 vis[1]=true; 17 queue<int>q; 18 q.push(1); 19 int temp,now,pre; 20 while(!q.empty()) 21 { 22 pre=q.front(); 23 q.pop(); 24 temp=pre; 25 for(int i=0;i<g[pre].size();i++) 26 { 27 int now=g[pre][i]; 28 if(!vis[now]) 29 { 30 vis[now]=true; 31 q.push(now); 32 } 33 } 34 } 35 memset(vis,0,sizeof(vis)); 36 vis[temp]=true; 37 int res=0; 38 queue<pair<int,int> >qq; 39 qq.push(make_pair(temp,0)); 40 pair<int,int>x,y; 41 while(!qq.empty()) 42 { 43 x=qq.front(); 44 qq.pop(); 45 for(int i=0;i<g[x.first].size();i++) 46 { 47 int now=g[x.first][i]; 48 if(!vis[now]) 49 { 50 vis[now]=1; 51 qq.push(make_pair(now,x.second+1)); 52 res=max(res,x.second+1); 53 } 54 } 55 } 56 return res+1; 57 } 58 int main() 59 { 60 scanf("%d",&T); 61 while(T--) 62 { 63 for(int i=1;i<maxn;i++)g[i].clear(); 64 scanf("%d%d",&n,&m); 65 int u,v; 66 for(int i=1;i<n;i++) 67 { 68 scanf("%d%d",&u,&v); 69 g[u].push_back(v); 70 g[v].push_back(u); 71 } 72 int r=bfs(); 73 while(m--) 74 { 75 scanf("%d",&u); 76 if(u<=r)printf("%d ",u-1); 77 else printf("%d ",r-1+(u-r)*2); 78 } 79 } 80 return 0; 81 }