记录编号 166185 评测结果 AAAAAAAAAAAAAA
题目名称 重建道路 最终得分 100
用户昵称 Gravatar0 是否通过 通过
代码语言 C++ 运行时间 0.004 s
提交时间 2015-06-14 15:05:28 内存使用 0.39 MiB
显示代码纯文本
#include<cstdio>
#define MIN(a,b) ((a)<(b)?(a):(b))

using namespace std;

int n,m,f[160][160],ls[160],rs[160],ans=0x7fffffff,root,son[160];
bool flag[160];

void DP(int x)
{
	if(!ls[x]&&!rs[x])
	{
		f[0][x]=1;
		f[1][x]=0;
		return ;
	}
	if(ls[x])
	    DP(ls[x]);
	if(rs[x])
	    DP(rs[x]);
	if(!ls[x])
	{
		f[0][x]=f[0][rs[x]]+1;
		for(int i=1;i<=m;i++)
		{
			f[i][x]=MIN(f[i-1][rs[x]],f[i][rs[x]]+1);
		}
		return;
	}
	if(ls[x])
	{
		for(int i=1;i<=m;i++)
		{
			f[i][x]=f[i-1][ls[x]];
		}
		int temp=f[m][x];
		if(x!=root)
		    temp++;
		if(temp<ans)
		{
			ans=temp;
		}
	}
	if(rs[x]&&ls[x])
	{
		for(int i=1;i<=m;i++)
		{
			f[i][x]=MIN(MIN(f[i][x]+f[0][rs[x]],f[i][rs[x]]+1),f[i-1][rs[x]]+son[x]); //..........
			for(int k=1;k<i;k++)
			{
				f[i][x]=MIN(f[i][x],f[k][ls[x]]+f[i-k-1][rs[x]]);
			}
		}
	}
	return;
}

int main()
{
	freopen("reroads.in","r",stdin);
	freopen("reroads.out","w",stdout);
	scanf("%d%d",&n,&m);
	if(n==m)
		ans=0;
	else
		if(m==1)
		    ans=1;
	for(int i=0;i<=n;i++)
	{
		for(int j=0;j<=m;j++)
		{
			f[j][i]=0x2fffffff;
		}
	}
	for(int i=1;i<n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		son[x]++;
		flag[y]=1;
		if(!ls[x])
		    ls[x]=y;
		else
		{
			int temp=ls[x];
			while(rs[temp])
			{
				temp=rs[temp];
			}
			rs[temp]=y;
		}
	}
 
 	for(int i=1;i<=n;i++)
 	{
		if(!flag[i])
		{
			root=i;
			break;
		}
 	}
 	DP(root);
 	printf("%d",ans);
 	return 0;
}