luogu P1272 重建道路 类似树上背包的树形dp
Posted 晴屿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P1272 重建道路 类似树上背包的树形dp相关的知识,希望对你有一定的参考价值。
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 500;
int f[N][N];
int h[N], e[N], ne[N], idx;
int n, p;
int ans = 0x3f3f3f3f;
int in[N];
void add(int a, int b)
{
e[idx] = b;
ne[idx] = h[a];
h[a] = idx ++;
}
void dfs(int u, int fa)
{
f[u][1]=in[u];//只保留这一个节点,那么就把所有临边都砍掉
for(int i = h[u]; i != -1; i = ne[i])
{
int v = e[i];
if(v == fa)
continue;
dfs(v, u);
//遍历完所有子节点,从下往上递归,
//父节点开始的时候 默认为只有f[u][1]
//当前子树去更新父节点信息的时候,默认这颗子树没有更新过
//也就是说 父节点中的信息中 要砍掉的边(包含的点),是不包含当前子树中的节点的
for(int j = p; j >= 1; j --)
for(int k = 1; k < j; k ++)
f[u][j] = min(f[u][j], f[u][k] + f[v][j - k] - 2);
}
}
int main()
{
memset(h, -1, sizeof h);
cin >> n >> p;
for(int i = 1; i < n; i ++)
{
int a, b;
cin >> a >> b;
in[a] ++ ;
in[b] ++ ;
add(a, b);
add(b, a);
}
memset(f, 0x3f, sizeof f);
dfs(1, -1);
for(int i = 1; i <= n; i ++)
ans = min(f[i][p], ans);
cout << ans << endl;
return 0;
}
以上是关于luogu P1272 重建道路 类似树上背包的树形dp的主要内容,如果未能解决你的问题,请参考以下文章