题意
输入n和k表示有n个地点和k个人(n个地点编号1..n)
接下来n-1行输入a、b表示地点ab之间有距离为1的通路
最后一行输入k个值表示哪些地点有人,求所有人聚在一起的最短时间。
(题意其实就是在一棵树上,多个节点有人。选择一个节点使得这些人各自到这个点的路径的最大值最小。)
题解
官方题解:
这道题剪掉不存在人的节点,接下来要求的其实就是树的直径。
该题dfs或bfs均可,dfs代码如下。
Code
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+5; vector<int>G[maxn]; bool book[maxn]; int ans,far;//far为离起始人位置最远的人的位置 void dfs(int x,int f,int step)//x为当前节点,f为父节点,step记录步数 { if(book[x]&&step>ans)//不断更新最远的人位置far和最远距离ans far=x,ans=step; for(int i=0;i<G[x].size();i++){ if(G[x][i]!=f)//令x点不会回到其父节点 dfs(G[x][i],x,step+1); } } int main() { int n,k,a,b; scanf("%d%d",&n,&k); for(int i=1;i<n;i++){ scanf("%d%d",&a,&b); G[a].push_back(b); G[b].push_back(a); } int x; for(int i=1;i<=k;i++){ scanf("%d",&x); book[x]=1;//标记哪个点有人 } dfs(x,0,0);//选任意一个人开始去深搜找离它最远的人 dfs(far,0,0);//将第一遍dfs找到的最远的人作为起点再去深搜找离它最远的人的距离 printf("%d ",(int)ceil(ans/2.0));//答案为ans/2上取整 }