给定的树中,任选一个点开始走,访问k个点,求最小路径长度。
思路:现求出树的直径r,如果k<=r那么只用走k-1的长度。
不然的话,就要走直径上链接的分支了,出了直径上的点还需要走k-r个点,此时的额外路径就是(k - r)*2。
/***************************************** Author :Crazy_AC(JamesQi) Time :2016 File Name : *****************************************/ // #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <climits> using namespace std; #define MEM(x,y) memset(x, y,sizeof x) #define pk push_back #define lson rt << 1 #define rson rt << 1 | 1 #define bug cout << "BUG HERE\n" typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; typedef pair<ii,int> iii; const double eps = 1e-10; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; int nCase = 0; const int maxn = 1e5 + 10; struct Edge { int from, to, nxt; Edge(){} Edge(int from,int to,int nxt) : from(from), to(to), nxt(nxt) {} }edges[maxn<<2]; int head[maxn], ecnt; int dis[maxn]; int bfs(int st) { memset(dis, INF,sizeof dis); queue<int> que; int pos, maxDis = 1; que.push(st), dis[st] = 1; while(!que.empty()) { int u = que.front(); que.pop(); if (dis[u] > maxDis) { pos = u; maxDis = dis[u]; } for (int i = head[u]; ~i;i = edges[i].nxt) { int v = edges[i].to; if (dis[v] != INF) continue; dis[v] = dis[u] + 1; que.push(v); } } return pos; } int solve() { int u = bfs(1); int v = bfs(u); return dis[v]; } int main(int argc, const char * argv[]) { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int t, n, k, m; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); int u, v; memset(head, -1,sizeof head), ecnt = 0; for (int i = 1;i < n;++i) { scanf("%d%d",&u,&v); edges[ecnt] = Edge(u, v, head[u]), head[u] = ecnt++; edges[ecnt] = Edge(v, u, head[v]), head[v] = ecnt++; } int maxDis = solve(); // cout << maxDis << endl; while(m--) { scanf("%d", &k); if (maxDis >= k) printf("%d\n", k - 1); else { printf("%d\n", (k - maxDis)*2 + (maxDis - 1)); } } } return 0; }