题目描述
X 国有 n 座城市,n−1 条长度为 1 的道路,每条道路连接两座城市,且任意两座城市都能通过若干条道路相互到达,显然,城市和道路形成了一棵树。
X 国国王决定将 k 座城市钦定为 X 国的核心城市,这 k 座城市需满足以下两个条件:
- 这 k 座城市可以通过道路,在不经过其他城市的情况下两两相互到达。
- 定义某个非核心城市与这 k 座核心城市的距离为,这座城市与 k 座核心城市的距离的最小值。那么所有非核心城市中,与核心城市的距离最大的城市,其与核心城市的距离最小。你需要求出这个最小值。
输入格式
第一行 2 个正整数 n,k。
接下来 n−1 行,每行 2 个正整数 u,v,表示第 u 座城市与第 v 座城市之间有一条长度为 1 的道路。
数据范围:
- 1≤k<n≤105。
- 1≤u,v≤n,u=v,保证城市与道路形成一棵树。
输出格式
一行一个整数,表示答案。
输入输出样例
输入 #1复制
6 3 1 2 2 3 2 4 1 5 5 6
输出 #1复制
1
说明/提示
【样例说明】
钦定 1,2,5 这 3 座城市为核心城市,这样 3,4,6 另外 3 座非核心城市与核心城市的距离均为 1,因此答案为 1。
代码实现:
#include<bits/stdc++.h>
#define loop(a, b, c) for(register int a = b; a <= c; a ++)
#define int64 long long
using namespace std;
inline int input(){
int val = 0; bool sign = 1; char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') sign = 0;
for(; isdigit(ch); ch = getchar()) val = val * 10 + ch - '0';
return sign ? val : -val;
}
queue <int> queue1, queue2;
const int MAXN = 5e5 + 10;
int cityCount, coreCityCount, adjHead[MAXN], result;
struct Edge {
int to, next;
} edges[MAXN];
int edgeCount = 0;
inline void addEdge(int from, int to) {
edgeCount ++;
edges[edgeCount].to = to;
edges[edgeCount].next = adjHead[from];
adjHead[from] = edgeCount;
}
int degree[MAXN];
int main(){
cityCount = input(); coreCityCount = input();
loop (i, 1, cityCount) adjHead[i] =-1;
loop (i, 1, cityCount-1) {
int u, v;
u = input(); v = input();
addEdge(u, v); addEdge(v, u);
degree[u] ++; degree[v] ++;
}
int remainingCities = cityCount;
loop (i, 1, cityCount) {
if (degree[i] == 1) {
queue1.push(i);
degree[i] --;
}
}
while(remainingCities > 0) {
result ++;
while (!queue1.empty()) {
int currentCity = queue1.front();
queue1.pop();
remainingCities --;
if (remainingCities == coreCityCount) {
cout<<result<<endl;
return 0;
}
for (int i = adjHead[currentCity]; i != -1; i = edges[i].next) {
int neighborCity = edges[i].to;
degree[neighborCity] --;
if (degree[neighborCity] == 1) queue2.push(neighborCity);
}
}
swap(queue1, queue2);
}
return 0;
}