AtCoderACGC001C Shorten Diameter

Description:

给定一个(n)个点的树,要求删去最少的点使树的致直径不超过k

Solution:

如果(k)为偶数,对于最终状态一定是以每一个点为根任何点的深度不能超过(k/2),那我们就以每个点为根求一下深度,然后再求一遍最小值,我们来看(k)为奇数时,我们先钦定一条边固定,分别以两端为根求深度,将问题转化为(k)为偶数即可

Code:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int MAXX=2010;
struct node
{
	int x,y;
}e[MAXX];
int head[MAXX],ver[MAXX<<1],nxt[MAXX<<1],deep[MAXX];
int n,k,tot;
inline void add(int x,int y){
	ver[++tot]=y;
	nxt[tot]=head[x];
	head[x]=tot;
}
inline void dfs(int x,int f,int dp){
	deep[x]=dp;
	for(int i=head[x];i;i=nxt[i]){
		int y=ver[i];
		if(y==f)continue;
		dfs(y,x,dp+1);
	}
} 
int main(){
   scanf("%d%d",&n,&k);
   for(int i=1;i<n;++i){
   	scanf("%d%d",&e[i].x,&e[i].y);
   	add(e[i].x,e[i].y);
   	add(e[i].y,e[i].x);
   }
   int ans=0x3f3f3f3f;
   if(k&1){
      for(int i=1;i<n;++i){
      	int cnt=0;
      	dfs(e[i].x,e[i].y,0);
      	dfs(e[i].y,e[i].x,0);
      	for(int j=1;j<=n;++j)if(deep[j]>(k-1)/2)cnt++;
      	ans=min(ans,cnt);
      } 
   }
   else {
   	  for(int i=1;i<=n;++i){
   	  int cnt=0;
      dfs(i,0,0);
      for(int j=1;j<=n;++j)if(deep[j]>k/2)cnt++;
      ans=min(ans,cnt);
   	  }
   	}
   	cout<<ans;
   	return 0;
}
原文地址:https://www.cnblogs.com/ARTlover/p/9578121.html