#include<iostream>
using namespace std;
#define MAXN 200
#define inf 0x300
struct edge { //树的边
int v;
int next;
}e[MAXN];
//size[i]为以i为根的树的节点数目
int first[MAXN], size[MAXN], p;
int f[MAXN][MAXN][2]; //f[i][j][]表示以i为根节点,保留j个节点
//所需要删去的边的最小数目
//f[i][x][0]表示以i为根的树中,获得一棵x个节点的子树(不含i),最少需要删除多少边
//f[i][x][1]表示以i为根的树中,获得一棵x个节点的子树(含i),最少需要删除多少边
int min(int x, int y)
{
if (x < y)
return x;
return y;
}
void ini(int n);
void dfs(int index);
void add(int index, int x, int y);
int main()
{
int n;
cin >> n >> p;
for (int i = 1; i < n; i++)
{
int x, y;
cin >> x >> y;
add(i, x, y);
}
ini(n);
dfs(1);
cout << min(f[1][p][0], f[1][p][1]);
return 0;
}
void ini(int n)
{
for (int i = 1; i <= n; i++)
for (int j = 0; j <= p; j++)
for (int k = 0; k <= 1; k++)
f[i][j][k] = inf;
}
void dfs(int index)
//遍历以index为根的树
{
f[index][0][0] = f[index][1][1] = 0;
size[index] = 1;
for (int l = first[index]; l; l = e[l].next)
//遍历所有index的子节点
{
int v = e[l].v;
dfs(v); //遍历子节点以得到子节点的数目,此时没有删边
size[index] += size[v];
int tmp[MAXN];
for (int x = 1; x <= min(p, size[index]); x++) //遍历所有可能的结点数
{
//min里的第二个为不删除index->x的边
//min里的第三个为删除index->x的边
f[index][x][0] = min(f[index][x][0], min(f[v][x][0], f[v][x][1] + 1));
tmp[x] = inf;
//表示都不删除
for (int y = 1; y <= min(x - 1, size[v]); y++)
tmp[x] = min(tmp[x], f[index][x - y][1] + f[v][y][1]);
tmp[x] = min(tmp[x], f[index][x][1] + 1);
}
for (int x = 1; x <= min(p, size[index]); x++)
f[index][x][1] = tmp[x];
}
}
void add(int index, int x, int y)
//加树的边
{
e[index].v = y;
e[index].next = first[x];
first[x] = index;
}
03-10
600