YY_More

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

我才发现我这么水。原打算随便再找道题早上热身,结果WA一直到现在。改了一天,结果发现是最白痴的错误。

这道题本质上还是树形的背包,但是枚举的时候要多考虑以某儿子为根的树被整个砍掉的情况。

//By YY_More
#include<cstdio>
#include<iostream>
using namespace std;
struct edge{
	int point;
	edge *next;
};
edge *g[151];
int N,P,x,y,root,F[151][151],goin[151];
int INF=200;
void insert(int father,int son){
	edge *p=new edge;
	goin[son]++;
	(*p).point=son;
	(*p).next=g[father];
	g[father]=p;
}	
void dp(int x){
	edge *p=g[x];
	F[x][1]=0;
	while (p!=NULL){
		dp((*p).point);
		for (int i=P;i>0;i--){
			if (F[x][i]==INF) continue;
			for (int j=1;j<=P-i;j++){
				if (F[(*p).point][j]==INF) break;
				if (F[(*p).point][j]+F[x][i]<F[x][i+j]) F[x][i+j]=F[(*p).point][j]+F[x][i];
			}	
			F[x][i]++;
		}	
		p=(*p).next;
	}
}	
int main(){
	scanf("%d%d",&N,&P);
	for (int i=1;i<N;i++){
		scanf("%d%d",&x,&y);
		insert(x,y);
	}
	for (int i=1;i<=N;i++)
		if (goin[i]==0) root=i;
	fill(&F[0][0],&F[151][151]+1,INF);
	dp(root);		
	int ans=F[root][P];
	for (int i=1;i<=N;i++)
		if (F[i][P]!=INF&&F[i][P]+1<ans) ans=F[i][P]+1;
	printf("%d\n",ans);
	return 0;
}
posted on 2011-07-06 16:47  YY_More  阅读(200)  评论(0编辑  收藏  举报