Description

The cows have reconstructed Farmer John's farm, with its N barns (1 <= N <= 150, number 1..N) after the terrible earthquake last May. The cows didn't have time to rebuild any extra roads, so now there is exactly one way to get from any given barn to any other barn. Thus, the farm transportation system can be represented as a tree.

Farmer John wants to know how much damage another earthquake could do. He wants to know the minimum number of roads whose destruction would isolate a subtree of exactly P (1 <= P <= N) barns from the rest of the barns.

Input

* Line 1: Two integers, N and P

* Lines 2..N: N-1 lines, each with two integers I and J. Node I is node J's parent in the tree of roads.

Output

A single line containing the integer that is the minimum number of roads that need to be destroyed for a subtree of P nodes to be isolated.

Sample Input

11 6
1 2
1 3
1 4
1 5
2 6
2 7
2 8
4 9
4 10
4 11


 Sample Output 2 Hint [A subtree with nodes (1, 2, 3, 6, 7, 8) will become isolated if roads 1-4 and 1-5 are destroyed.]  Source

dp[s][i]:记录s结点，要得到一棵j个节点的子树去掉的最少边数
考虑其儿子k
1）如果不去掉k子树，则
dp[s][i] = min(dp[s][j]+dp[k][i-j])  0 <= j <= i

2）如果去掉k子树，则
dp[s][i] =  dp[s][i]+1
总的为
dp[s][i] = min (min(dp[s][j]+dp[k][i-j]) ,  dp[s][i]+1 )

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int root,brother[155],son[155],father[155];
int n,p;
int dp[155][155];
void dfs(int rt)
{
for(int i=0;i<=p;i++)
dp[rt][i]=10000000;
dp[rt][1]=0;
int k=son[rt];
while(k)
{
dfs(k);
for(int i=p;i>=1;i--)
{
int temp=dp[rt][i]+1;
for(int j=1;j<i;j++)
temp=min(temp,dp[rt][i-j]+dp[k][j]);
dp[rt][i]=temp;
}
k=brother[k];
}
}
int solve()
{
dfs(root);
int ans=dp[root][p];
for(int i=1;i<=n;i++)
ans=min(ans,dp[i][p]+1);
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&p))
{
memset(brother,0,sizeof(brother));
memset(son,0,sizeof(son));
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
father[y]=x;
brother[y]=son[x];
son[x]=y;
}
for(int i=1;i<=n;i++)
{
if(!father[i])
{
root=i;
break;
}
}
printf("%d\n",solve());
}
}

• 本文已收录于以下专栏：

• y990041769
• 2015年04月30日 20:02
• 1382

Rebuilding Roads Time Limit:1000MS     Memory Limit:30000KB     64bit IO Format:%lld & %llu Submit S...
• yjf3151731373
• 2016年10月30日 19:42
• 53

## [POJ 1947] Rebuilding Roads 树形dp

http://poj.org/problem?id=1947题意：输入 n, m 表示一棵树有 n 个顶点，然后输入 n-1 条边，要求删除一些边使得树中剩下 m 个点，问最少要删除多少边。...
• AcmHonor
• 2015年08月06日 19:40
• 314

## POJ 1947 Rebuilding Roads - 树形DP

• x_1023
• 2017年09月29日 23:34
• 61

## poj 1947 Rebuilding Roads 树形dp

poj 1947 Rebuilding Roads http://poj.org/problem?id=1947 题意：给定N个点，之间有路N-1条，且从一点到另一点只有一种走法，问去掉几条路，可...
• qianxun136930775
• 2012年08月20日 16:50
• 149

## POJ 1947 Rebuilding Roads 树形dp

http://poj.org/problem?id=1947 题意：给你一棵有N个结点的树， 要求从树中剪掉一些边， 使得最后得到的子树恰好有P个结点。 思路：树形dp。用dp[i][j] 表示在...
• ivan_zjj
• 2012年04月04日 11:16
• 424

## POJ 1947 Rebuilding Roads （树形dp + 01背包）

• Infinity_Izayoi
• 2016年07月22日 21:09
• 119

## poj 1947 Rebuilding Roads 树形dp背包

dp[i][j] 代表以i为根 大小为j需要拆的最小边数 然后dp 注意边界处理对于每个子节点x不连的话dp[i][j] + 1连得话就是 dp[i][j - k] + dp[x][k]; 然后除...
• acblacktea
• 2016年09月03日 15:14
• 184

Description 给出一棵有n个节点的树，问如何减去最少的边，得到一个含有p个节点的子树 Input 第一行两个整数n和p，之后n-1行每行两个整数a和b表示a和b间有一条边 Outpu...
• V5ZSQ
• 2015年11月01日 14:12
• 529