参考资料:
[1]:官方题解(提取码:5kim)
[2]:标程(提取码:76lh)
A.meeting(树的直径)
•题意
有一颗由 n 个节点组成的树;
树上标记了 k 个点;
求树上某个节点到这 k 个点的最远距离的最小值;
•题解
•Code
View Code1 #include<bits/stdc++.h> 2 using namespace std; 3 #define mem(a,b) memset(a,b,sizeof(a)) 4 const int maxn=1e5+50; 5 6 int n,k; 7 int num; 8 int head[maxn]; 9 struct Edge 10 { 11 int to; 12 int next; 13 }G[maxn<<1]; 14 void addEdge(int u,int v) 15 { 16 G[num]={v,head[u]}; 17 head[u]=num++; 18 } 19 int x[maxn]; 20 int dis[maxn]; 21 22 void DFS(int u,int f,int d) 23 { 24 dis[u]=d; 25 for(int i=head[u];~i;i=G[i].next) 26 { 27 int v=G[i].to; 28 29 if(v != f) 30 DFS(v,u,d+1); 31 } 32 } 33 int Solve() 34 { 35 if(k <= 1) 36 return 0; 37 38 DFS(x[1],x[1],0); 39 40 int cur=x[1]; 41 for(int i=1;i <= k;++i) 42 if(dis[cur] < dis[x[i]]) 43 cur=x[i]; 44 45 DFS(cur,cur,0); 46 47 int ans=0; 48 for(int i=1;i <= k;++i) 49 ans=max(ans,dis[x[i]]); 50 51 return (ans+1)/2; 52 } 53 void Init() 54 { 55 num=0; 56 mem(head,-1); 57 } 58 int main() 59 { 60 Init(); 61 scanf("%d%d",&n,&k); 62 63 for(int i=1;i < n;++i) 64 { 65 int u,v; 66 scanf("%d%d",&u,&v); 67 68 addEdge(u,v); 69 addEdge(v,u); 70 } 71 for(int i=1;i <= k;++i) 72 scanf("%d",x+i); 73 74 printf("%d\n",Solve()); 75 76 return 0; 77 }