突然感觉自己代码写的好丑= =今天突然手不听话了疯狂打错字= =
显然树形DP,表示fi,j是在第i个点,有j个点连着的最小值
显然看每一棵子树的转移,显然背包
Problem: 1947 User: BPM136
Memory: 816K Time: 0MS
Language: G++ Result: Accepted
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<utility>
#include<map>
#include<queue>
#include<bitset>
#define LL long long
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define efo(i,x) for(int i=last[x];i!=0;i=e[i].next)
using namespace std;
inline LL read()
{
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
#define N 155
#define inf 100000
int f[N][N];
int n,m;
int fa[N];
struct edge
{
int y,next;
}e[N*N];
int last[N],ne=0;
int root=0;
void add(int x,int y)
{
e[++ne].y=y;e[ne].next=last[x];last[x]=ne;
}
int temp[N];
void dfs(int x)
{
// fo(i,1,siz[x])f[x][i]=1;
fo(i,0,m)f[x][i]=inf;f[x][1]=0;
efo(i,x)
{
dfs(e[i].y);
fd(k,m,1)
{
int tot=f[x][k]+1;
fo(j,1,k-1)
tot=min(tot,f[x][j]+f[e[i].y][k-j]);
f[x][k]=tot;
}
}
// f[x][0]=0;
// fo(i,1,siz[x])f[x][i]++;
// cout<<x<<' '<<siz[x]<<' '<<f[x][1]<<' '<<f[x][2]<<' '<<f[x][3]<<endl;
}
/*
void predfs(int x)
{
siz[x]=1;
efo(i,x)
{
predfs(e[i].y);
siz[x]+=siz[e[i].y];
}
}
*/
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(f,0,sizeof(f));
memset(fa,0,sizeof(fa));
ne=0;memset(last,0,sizeof(last));
fo(i,1,n-1)
{
int x,y;scanf("%d%d",&x,&y);
add(x,y);
fa[y]=x;
}
fo(i,1,n)
if(fa[i]==0)
{
root=i;
break;
}
// predfs(root);
dfs(root);
int ans=f[root][m];
fo(i,1,n)
if(i!=root)
ans=min(ans,f[i][m]+1);
cout<<ans<<endl;
}
return 0;
}