健康監測計劃

2020-09-28 16:00:10

題目連結:健康監測計劃


顯然從葉子貪心是最優的。於是我們可以想到先取葉子,然後把葉子刪掉,然後繼續取葉子。

一共取 k/2 次葉子,如果k是奇數,最後再任意取一個點即可。

所以我們樹上拓撲即可。


AC程式碼:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e6+10;
int n,k,deg[N],dep[N],res;
vector<int> g[N]; queue<int> q;
signed main(){
	cin>>n>>k;
	for(int i=1,a,b;i<n;i++){
		scanf("%d %d",&a,&b); deg[a]++,deg[b]++;
		g[a].push_back(b),g[b].push_back(a);
	}
	if(k==0||k==1) return cout<<k,0;
	for(int i=1;i<=n;i++) if(deg[i]==1) q.push(i),dep[i]=1;
	while(q.size()){
		int u=q.front(); q.pop(); res++;
		for(int to:g[u]){
			dep[to]=max(dep[to],dep[u]+1);
			if(dep[to]<=k/2&&--deg[to]==1) q.push(to);
		}
	}
	cout<<min(n,res+k%2);
	return 0;
}