树的直径的求法,任取一点u为起点,BFS出一条最长路径,假设此时终点为v,则再次以v为起点,再BFS出一条最长路径v-w。可以得出树的直径即为所求。。证明略。可以直接BFS或者DFS都行,来发水题~
/****************************** * author :crazy_石头 * data structure: 树的直径 * created time:2013/11/4 19:02 * Pro:HDU 4607 * Judge Status:Accepted * Memory:3128K * Time:453MS *******************************/ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> using namespace std; #define rep(i,h,n) for(int i=(h);i<=(n);i++) #define INF 1<<29 const int maxn=100000+5; struct Edge { int to; int next; }edge[maxn<<2]; int head[maxn],dis[maxn],vis[maxn]; int cnt,tmp,n,m; inline void addedge(int u,int v) { edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt++; } inline void makemap(int u,int v) { addedge(u,v); addedge(v,u); } inline int BFS(int s) { queue<int> q; while(!q.empty()) q.pop(); rep(i,1,n) dis[i]=INF; memset(vis,0,sizeof(vis)); q.push(s); vis[s]=1; dis[s]=0; while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=1; for(int i=head[u];~i;i=edge[i].next) { int v=edge[i].to; if(dis[v]>dis[u]+1) { dis[v]=dis[u]+1; tmp=v; if(!vis[v]) { vis[v]=1; q.push(v); } } } } return tmp; } inline void init() { cnt=0; memset(head,-1,sizeof(head)); } int main() { int test; scanf("%d",&test); while(test--) { scanf("%d%d",&n,&m); init(); rep(i,1,n-1) { int u,v; scanf("%d%d",&u,&v); makemap(u,v); } tmp=BFS(1); tmp=BFS(tmp); while(m--) { int h; scanf("%d",&h); if(h<=dis[tmp]+1) printf("%d\n",h-1); else printf("%d\n",dis[tmp]+(h-(dis[tmp]+1))*2); } } return 0; } |
* This source code was highlighted by YcdoiT. ( style: Autumn )