传送门

 

参考资料:

  [1]:官方题解(提取码:5kim)

  [2]:标程(提取码:76lh)

 

A.meeting(树的直径)

•题意

  有一颗由 n 个节点组成的树;

  树上标记了 k 个点;

  求树上某个节点到这 k 个点的最远距离的最小值;

•题解

  2019牛客暑期多校训练营(第四场)

•Code

 1 #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 }
View Code

相关文章: