转载博客
补充说明
之所以上图可以设一个点X,那是因为这是树的性质,任何两个点都可以通过某些路径使其连通
模板题
思路
首先建一棵树,然后对树上的k个点求一个最大直径D,然后D/2上取整
AC代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
vector<int>tree[maxn];
struct node{
int val;
int index;
node(){
val=0;
}
};
int start,top;
bool flag[maxn];
bool vis[maxn];
node ans;
void dfs(int x,int step){
if(vis[x]){
return ;
}
vis[x]=true;
if(step > ans.val && flag[x] ){
ans.val = step;
ans.index = x;
}
int Size = tree[x].size();
for(int i=0; i<Size; i++){
dfs(tree[x][i],step+1);
}
}
int main(){
int n, k;
scanf("%d%d", &n, &k);
memset(flag, false, sizeof(flag));
for(int i=1; i<=n-1; i++){
int x,y;
scanf("%d%d", &x, &y);
tree[x].push_back(y);
tree[y].push_back(x);
}
for(int i=1; i<=k; i++){
int temp;
scanf("%d", &temp);
start = temp;
flag[temp] = true;
}
dfs(start,0);///找到另外一个点
memset(vis, false, sizeof(vis));
top = ans.index;
dfs(top,0);
printf("%d\n", ans.val%2==0?ans.val/2:ans.val/2+1);
return 0;
}