1 4 2 3 2 1 2 4 2 2 4
1 4
题目大意:
一棵树树的直径:树上的最长简单路径;
直径的求法:
可以任意选择一个点开始进行bfs或者dfs;从而找到离该点最远的那个点;
再从找到的点出发,找到据该点的最远点,那么这两点就确定了树的一条直径,两点间距即为所求距离;
BFS的代码:
#include<cstdio> #include<cstring> #include<vector> #include<queue> using namespace std; const int maxn=110000; struct Node{ int x; int d; }; int flag,Max; bool vis[maxn]; vector<int> son[maxn]; queue<Node> Que; void BFS(int x) { int i; Node tmp,a; while(!Que.empty()) { Que.pop(); } tmp.x=x; tmp.d=1; Que.push(tmp); memset(vis,0,sizeof(vis)); vis[x]=1; flag=x; Max=1; while(!Que.empty()) { tmp=Que.front(); Que.pop(); if(tmp.d>Max) { Max=tmp.d; flag=tmp.x; } for(i=0;i<son[tmp.x].size();i++) { if(!vis[son[tmp.x][i]]) { vis[son[tmp.x][i]]=1; a.x=son[tmp.x][i]; a.d=tmp.d+1; Que.push(a); } } } } int main() { int T,N,M,K; int u,v,i; scanf("%d",&T); while(T--) { scanf("%d%d",&N,&M); for(i=1;i<=N;i++) son[i].clear(); for(i=1;i<N;i++) { scanf("%d%d",&u,&v); son[u].push_back(v); son[v].push_back(u); } BFS(1); // printf("max=%d flag=%d\n",Max,flag); BFS(flag); // printf("max=%d flag=%d\n",Max,flag); while(M--) { scanf("%d",&K); if(K<=Max) printf("%d\n",K-1); else printf("%d\n",Max-1+(K-Max)*2); } } return 0; }
DFS的代码:
#include<cstdio> #include<cstring> #include<vector> using namespace std; const int maxn=110000; int flag,Max; bool vis[maxn]; vector<int> son[maxn]; void DFS(int x,int d) { if(d>Max) { Max=d; flag=x; } for(int i=0;i<son[x].size();i++) { if(!vis[son[x][i]]) { vis[son[x][i]]=true; DFS(son[x][i],d+1); } } } int main() { int T,N,M,K; int u,v,i; scanf("%d",&T); while(T--) { scanf("%d%d",&N,&M); for(i=1;i<=N;i++) son[i].clear(); for(i=1;i<N;i++) { scanf("%d%d",&u,&v); son[u].push_back(v); son[v].push_back(u); } memset(vis,0,sizeof(vis)); vis[1]=true; Max=1; flag=1; DFS(1,1); // printf("max=%d flag=%d\n",Max,flag); memset(vis,0,sizeof(vis)); vis[flag]=1; Max=1; DFS(flag,1); // printf("max=%d\n",Max); while(M--) { scanf("%d",&K); if(K<=Max) printf("%d\n",K-1); else printf("%d\n",Max-1+(K-Max)*2); } } return 0; }