链接:https://acm.ecnu.edu.cn/contest/317/problem/B/
思路:
按k我们来考虑k=0,那么肯定一个都不放,k=1,那么显然只能放一个,k=2呢?所有叶子结点都放,先去想k=4,那就是把叶子结点都去了,然后新的树中的叶子结点。k=3呢?就是k=4中,新选的点中随便取一个。这样一直把外圈缩进k/2次,所有的叶子结点就都是答案,那么如何判断k/2次呢,记录个深度,如果深度<=k/2并且它是叶子结点就算是要去的点。用queue把叶子结点放进来,并且每个叶子结点更新它对连的点,时间复杂度O(n)
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+7;
queue<int> q;
vector<int> g[maxn];
int d[maxn];
int dep[maxn];
struct Node{
int x, d;
bool operator < (const Node n1) const{
return d < n1.d;
}
};
int main()
{
int n, k;
cin>>n >> k;
for(int i = 1; i <= n-1; i++){
int u, v;
cin >> u >> v;
g[u].push_back(v);g[v].push_back(u);
d[u]++;d[v]++;
}
if(k == 0){
cout << 0 << endl; return 0;
}
else if(k == 1) {
cout << 1 << endl; return 0;
}
for(int i = 1; i <= n; i++) {
if(d[i] == 1) {
q.push(i);
dep[i] = 1;
}
}
int ans = 0;
while(!q.empty()){
int tmp = q.front(); q.pop();
ans++;
for(auto to : g[tmp]){
dep[to] = max(dep[to], dep[tmp]+1);
if(dep[to] <= k/2 && --d[to] == 1){
q.push(to);
}
}
}
cout << min(n, ans+k%2);
}
京公网安备 11010502036488号