POJ1947 Rebuilding Roads[树形背包]

Rebuilding Roads

Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 11495   Accepted: 5276

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

USACO 2002 February


题意:给定一棵节点数为n的树,问从这棵树最少删除几条边使得某棵子树的节点个数为p


一开始想了个倒着选了几条边,其实正着也可以,先d[i][1]=子节点数量

d[i][j]表示以i为根的子树节点数为j最少删几条边

注意size要加上自己

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=155,INF=1e9;
int read(){
    char c=getchar();int x=0,f=1;
    while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1; c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘; c=getchar();}
    return x*f;
}
int n,m,u,v,w,ind[N];
struct edge{
    int v,w,ne;
}e[N<<1];
int h[N],cnt=0;
void ins(int u,int v){
    cnt++;
    e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
}
int d[N][N],size[N];
void dfs(int u){
    int child=0;size[u]=1;//!self
    for(int i=h[u];i;i=e[i].ne){
        int v=e[i].v;
        dfs(v);
        size[u]+=size[v];
        child++;
    }
    if(!child) {size[u]=1;d[u][1]=0;return;}//printf("size %d %d\n",u,size[u]);

    d[u][1]=child;
    for(int j=2;j<=size[u];j++) d[u][j]=INF;
    for(int i=h[u];i;i=e[i].ne){
        int v=e[i].v;
        for(int j=size[u];j>=1;j--){
            int t=min(j-1,size[v]);
            for(int k=1;k<=t;k++) d[u][j]=min(d[u][j],d[u][j-k]+d[v][k]-1);
        }
    }

    //for(int i=1;i<=size[u];i++) printf("d %d %d %d\n",u,i,d[u][i]);
}
int main(int argc, const char * argv[]) {
    n=read();m=read();
    for(int i=1;i<=n-1;i++){
        u=read();v=read();ins(u,v);ind[v]++;
    }
    int root=-1;
    for(int i=1;i<=n;i++) if(!ind[i]) {root=i;break;}
    dfs(root);
    int ans=INF;
    for(int i=1;i<=n;i++) if(size[i]>=m) ans=min(ans,d[i][m]+(i==root?0:1));
        //,printf("ans %d %d\n",i,d[i][m]);
    printf("%d",ans);
    return 0;
}
时间: 2024-08-11 19:44:25

POJ1947 Rebuilding Roads[树形背包]的相关文章

POJ 1947 Rebuilding Roads (树形dp 经典题)

Rebuilding Roads Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 9499   Accepted: 4317 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

[poj 1947] Rebuilding Roads 树形DP

Rebuilding Roads Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 10653 Accepted: 4884 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 co

POJ-1947 Rebuilding Roads (树形DP+分组背包)

题目大意:将一棵n个节点的有根树,删掉一些边变成恰有m个节点的新树.求最少需要去掉几条边. 题目分析:定义状态dp(root,k)表示在以root为根节点的子树中,删掉一些边变成恰有k个节点的新树需要删去的最少边数.对于根节点root的某个儿子son,要么将son及其所有的子节点全部删掉,则dp(root,k)=dp(root,k)+1,只需删除root与son之间的边:要么在son的子树中选出一些边删掉,构造出有j个节点的子树,状态转移方程为dp(root,k)=max(dp(root,k),

POJ1947 Rebuilding Roads

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 g

[POJ 1947]Rebuilding Roads (树形dp)

题目链接:http://poj.org/problem?id=1947 题目大意:给你一棵树,树上N个节点.问最少拆掉多少条边使得存在一个联通块,有P个节点. 树形dp,设计状态:dp[u][i]代表以u为根节点的剩下i个节点最少需要拆掉多少条边. 状态转移:dp[u][i+j] = min(dp[u][i+j],dp[u][i]+dp[v][j]-1); 其中v是u的儿子节点. 相当于在树上跑01背包,即每个儿子节点去掉剩下j个的但是要连上u-v边,或者不去掉剩下j个的. 代码: 1 impo

【树形dp】Rebuilding Roads

[POJ1947]Rebuilding Roads Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 11934   Accepted: 5519 Description The cows have reconstructed Farmer John's farm, with its N barns (1 <= N <= 150, number 1..N) after the terrible earthquake las

Poj 1112 Rebuilding Roads(树形DP+背包)

题意:给你由N个点构成一颗树,问要孤立出一个有P个节点的子树最少需要删除多少条边.N的范围最大为150 N的范围不大,很容易想到在树上面做背包.把每个节点都看成一个背包,然后把每个儿子节点都看成是一组物品.为什么是一组呢,那是因为假设以儿子为根的节点的子树有S个节点,那么就有S+1种情况,要么将这整棵子树舍弃,要么从这个子树中取1-S个节点. 设f[i][j]为以i为根节点的子树,孤立出以i为根节点,一共含有j个节点的子树最少需要删除的边数(不包括删除i和他父亲的连接的那条边(假设i不是根节点)

树形DP [POJ 1947] Rebuilding Roads

Rebuilding Roads Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 9249   Accepted: 4198 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

poj 1947 Rebuilding Roads 【树形DP】 【求至少删去树中 多少条边 使得树中节点数为P】

Rebuilding Roads Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 10066   Accepted: 4595 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. Th