求出树的直径d。当k<=d的时候,显然直接在直径上走就行了,当k>d的时候,便是直径d的长度 加上 多出来的点数*2.
#include<iostream> #include<algorithm> #include<vector> #include<cstdio> #include<cstring> #define FF(i, a ,b) for(int i=a; i<b; i++) #define FD(i, a ,b) for(int i=a; i>b; i--) #define REP(i, n) for(int i=0; i<n; i++) #define LL long long #define CLR(a, b) memset(a, b, sizeof(a)) #define PB push_back using namespace std; const int maxn = 111111; int n, m, dist, k, end; vector<int> G[maxn]; void dfs(int x, int fa, int d) { int nc = G[x].size(); if(nc == 1) { if(d > dist) { dist = d; end = x; } } REP(i, nc) { int v = G[x][i]; if(v != fa) { dfs(v, x, d+1); } } } int main() { int T, a, b; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); REP(i, n+1) G[i].clear(); FF(i, 1, n) { scanf("%d%d", &a, &b); G[a].PB(b); G[b].PB(a); } dist = 0; dfs(1, -1, 0); dfs(end, -1, 0); dist++; while(m--) { scanf("%d", &k); if(k <= dist) printf("%d ", k-1); else printf("%d ", dist - 1 + (k-dist)*2); } } return 0; }