/*
01背包(最小价值) + 树形DP,做的第一道树形DP问题
思路:d[i][j]:以i为跟的树,选j个节点,根必选
原来一直Runtime Error,最后发现①处的问题,漏了N
*/
#include <cstdio>
#include <cstring>
const int nMax = 157;
const int INF = 0x3fffffff;
int next[nMax];
int head[nMax];
int fa[nMax];
int d[nMax][nMax];
int N, P;
void dfs(int root)
{
int i, j;
for(i = 1; i <= P; ++ i)
d[root][i] = INF;
d[root][1] = 0;
int p = head[root];
while(p != -1)
{
dfs(p);
for(i = P; i >= 1; -- i)
{
d[root][i] = d[root][i] + 1;
for(j = 1; j < i; ++ j)
{
if(d[root][i] > d[p][j] + d[root][i - j])
d[root][i] = d[p][j] + d[root][i - j];
}
}
p = next[p];
}
}
int main()
{
while(scanf("%d%d", &N, &P) != EOF)
{
int i;
memset(head, -1, sizeof(head));
memset(fa, -1, sizeof(fa));
for(i = 1; i < N; ++ i)
{
int a, b;
scanf("%d%d", &a, &b);
next[b] = head[a];
head[a] = b;
fa[b] = a;
}
int root;
for(i = 1; i <= N; ++ i)//①
{
if(fa[i] == -1)
{
root = i;
break;
}
}
dfs(root);
int _min = d[root][P];
for(i = 1; i <= N; ++ i)
{
if(d[i][P] + 1 < _min)
_min = d[i][P] + 1;
}
printf("%d\n", _min);
}
return 0;
}
POJ 1947 Rebuilding Roads(树形DP + 01背包)
最新推荐文章于 2018-11-14 16:42:16 发布