版权声明:本文为博主原创文章,不管你喜不喜欢都请在注明作者后转载~( ̄▽ ̄~) https://blog.csdn.net/C20190102/article/details/82943999
题目
题目大意
我们称一个直径不超过 的数为好树,给定一个 个结点的无根树,至少需要删除多少个点,它才能变成一个好树?
思路
根据树的直径的性质:
- 若 是偶数,枚举一个点作为好树的中心,那么这个点到任何一个点的距离都应小于等于 ,需要删掉的点就是到它距离超过这么多的点。
- 若 是奇数,枚举一条边 作为好树的中心边,那么任何一个点到 或到 的距离都应小于等于 ,请自行脑补画面。
时间复杂度 。
代码
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
#define MAXN 2000
struct Edge{
int v,u;
}E[MAXN+5];
int N,K;
vector<int> G[MAXN+5];
//有多少个点需要删掉
int dfs(int u,int f,int MaxD,int D){
int ret=0;
if(D>MaxD)
ret++;
for(int i=0;i<int(G[u].size());i++){
int v=G[u][i];
if(v!=f)
ret+=dfs(v,u,MaxD,D+1);
}
return ret;
}
int main(){
scanf("%d%d",&N,&K);
for(int i=1;i<N;i++){
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
E[i]=(Edge){u,v};
}
int Ans=N;
if(K&1)//两种情况
for(int i=1;i<N;i++)
Ans=min(Ans,dfs(E[i].u,E[i].v,K/2,0)+dfs(E[i].v,E[i].u,K/2,0));
else
for(int i=1;i<=N;i++)
Ans=min(Ans,dfs(i,-1,K/2,0));
printf("%d",Ans);
}