2019牛客多校训练第四场A.meeting(dfs / bfs)

题目传送门

题意

输入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上取整
}
原文地址:https://www.cnblogs.com/HOLLAY/p/11377804.html