2019牛客多校第四场 A.meeting

题意 :

   n个节点,有k个人,求k个人到某一个节点的最短时间

题解:

   考虑距离最远的两个关键点,设它们的距离为d,d/2上取整即为答案。

必要性:这两个人要碰面,必然要走至少d/2步。

充分性:我们取两人路径中和一头距离为d/2上取整的一个点,让所有人在这相聚。如 果有一个人在d/2时间内到不了,那么它和路径两头中与它远的那一头的距离大于d,与 最远的假设矛盾。

从任意一个关 键点开始,找到离它最远的关键点x,再从 x 开始dfs,找到的新的最远点和 x 形成的就是直径。

#include 
using namespace std;
vector a[100005];
int v[100005], top, sum = 0;
void dfs(int p, int f, int step){
	if(v[p] && step > sum){
		top = p;
		sum = step;
	}
	for(int i = 0; i < a[p].size(); i++){
		if(a[p][i] != f){
			dfs(a[p][i], p, step+1);
		}
	}
}
int main(){
	int n, k, x, y, t;
	cin >> n >> k;
	for(int i = 1; i < n; i++){
		cin >> x >> y;
		a[x].push_back(y);
		a[y].push_back(x);
	}
	memset(v, 0, sizeof(v));
	for(int i = 1; i <= k; i++){
		cin >> t;
		v[t] = 1;
	}
	dfs(t, 0, 1);
	dfs(top, 0, 1);
	cout << sum/2 << endl;
	return 0;
}

 

你可能感兴趣的:(搜索)