树形DP。。。。。
Rebuilding Roads
Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 8188 Accepted: 3659

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

现在设dp[j]表示以i为根的子树中节点个数为j的最少删除边数

状态转移方程: dp[1] = tot                                         (tot为他的子节点个数)

dp[j] = min(dp[j],dp[k]-1+dp[s][j-k])  (1<=i<=n,2<=j<=sum(节点总和),1<=k<j,s为i子节点)(i中已有k个节点并从s中选择j-k个,算最少删除边数,s选上所以i->s的边不需删除,所以-1)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

const int INF=0x3f3f3f3f;

int dp[200][200],sum[200],N,P;
vector<int> g[200];
bool vis[200];

void Tree_DP(int s)
{
    if(vis[s]) return;
    int tot = 0;
    vis[s]=true;sum[s]=1;
    for(int i=0;i<g[s].size();i++)
    {
        int v=g[s];
        if(vis[v]) continue;
        Tree_DP(v);
        sum[s]+=sum[v];
        tot++;
    }
    dp[s][1]=tot;
    for(int i=0;i<g[s].size();i++)
    {
        int v=g[s];
        for(int j=sum[s];j>=2;j--)
        {
            for(int k=1;k<j;k++)
            {
                if(dp[s][k]!=INF&&dp[v][j-k]!=INF)
                {
                    dp[s][j]=min(dp[s][j],dp[s][k]+dp[v][j-k]-1);
                }
            }
        }
    }
}

int main()
{
    while(scanf("%d%d",&N,&P)!=EOF)
    {
        for(int i=0;i<N+10;i++)
            g.clear();
        for(int i=0;i<N-1;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            g[a].push_back(b);
            g.push_back(a);
        }
        memset(dp,63,sizeof(dp));
        memset(vis,false,sizeof(vis));
        memset(sum,0,sizeof(sum));
        Tree_DP(1);
        int ans=INF;
        for(int i=1;i<=N;i++)
        {
            if(i==1)
                ans=min(ans,dp[P]);
            else ans=min(dp[P]+1,ans);
        }
        printf("%d\n",ans);
    }
    return 0;
}

* This source code was highlighted by YcdoiT. ( style: Codeblocks )

POJ 1947 Rebuilding Roads的更多相关文章

  1. [poj 1947] Rebuilding Roads 树形DP

    Rebuilding Roads Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 10653 Accepted: 4884 Des ...

  2. POJ 1947 Rebuilding Roads 树形DP

    Rebuilding Roads   Description The cows have reconstructed Farmer John's farm, with its N barns (1 & ...

  3. POJ 1947 Rebuilding Roads 树形dp 难度:2

    Rebuilding Roads Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 9105   Accepted: 4122 ...

  4. DP Intro - poj 1947 Rebuilding Roads(树形DP)

    版权声明:本文为博主原创文章,未经博主允许不得转载. Rebuilding Roads Time Limit: 1000MS   Memory Limit: 30000K Total Submissi ...

  5. POJ 1947 Rebuilding Roads (树dp + 背包思想)

    题目链接:http://poj.org/problem?id=1947 一共有n个节点,要求减去最少的边,行号剩下p个节点.问你去掉的最少边数. dp[u][j]表示u为子树根,且得到j个节点最少减去 ...

  6. 树形dp(poj 1947 Rebuilding Roads )

    题意: 有n个点组成一棵树,问至少要删除多少条边才能获得一棵有p个结点的子树? 思路: 设dp[i][k]为以i为根,生成节点数为k的子树,所需剪掉的边数. dp[i][1] = total(i.so ...

  7. POJ 1947 Rebuilding Roads(树形DP)

    题目链接 题意 : 给你一棵树,问你至少断掉几条边能够得到有p个点的子树. 思路 : dp[i][j]代表的是以i为根的子树有j个节点.dp[u][i] = dp[u][j]+dp[son][i-j] ...

  8. POJ 1947 - Rebuilding Roads 树型DP(泛化背包转移)..

    dp[x][y]表示以x为根的子树要变成有y个点..最少需要减去的边树... 最终ans=max(dp[i][P]+t)  < i=(1,n) , t = i是否为整棵树的根 > 更新的时 ...

  9. DP Intro - poj 1947 Rebuilding Roads

    算法: dp[i][j]表示以i为根的子树要变成有j个节点的状态需要减掉的边数. 考虑状态转移的时候不考虑i的父亲节点,就当不存在.最后统计最少减去边数的 时候+1. 考虑一个节点时,有两种选择,要么 ...

随机推荐

  1. IAR使用记录

    1. Project-->Options... 更改器件:General-->Target-->Device 添加其它需包含的目录:C/C++ Compiler-->Prepr ...

  2. 数据结构算法C语言实现(十七)--- 5.1&5.2数组:定义、顺序表示及实现

    一.简述 理解数组位置的计算公式 LOC(j1, j2, ···, jn) = LOC(0, 0, ..., 0) + (b2 x ··· x bn x j1 + b3 x ··· x bn x j2 ...

  3. Simultaneous Tag Editing in IntelliJ IDEA 14.1

    If you're involved in web development and, for some reason, you haven't given a ride to IntelliJ IDE ...

  4. Codeforces 711E ZS and The Birthday Paradox

    传送门 time limit per test 2 seconds memory limit per test 256 megabytes input standard input output st ...

  5. centos安装CODEBLOCKS

    装了好多次系统,每次装的时候都有要在网上各种查,太麻烦了.所以决定记录一下,以后用到的时候会方便一些.当然,本文来源于网络,取百家之长,最重要的是本人已验证过,说明对本系统是可行的. 在CentOS7 ...

  6. Visual Studio原生开发的20条调试技巧(下)

    我的上篇文章<Vistual Studio原生开发的10个调试技巧>引发了很多人的兴趣,所以我决定跟大家分享更多的调试技巧.接下来你又能看到一些对于原生应用程序的很有帮助的调试技巧(接着上 ...

  7. Mobius 反演

    上次看莫比乌斯繁衍反演是一个月前,讲道理没怎么看懂.. 然后出去跪了二十天, 然后今天又开始看发现其实并不难理解   开个这个仅记录一下写过的题. HAOI 2011 B   这应该是莫比乌斯反演的模 ...

  8. css居中那点事儿

    css居中那点事儿 在css中对元素进行水平居中是非常简单的,然而使元素垂直居中就不是一件简单的事情了,多年以来,垂直居中已经成为了CSS领域的圣杯,因为它是极其常见的需求,但是在实践中却不是一件简单 ...

  9. uC/OS-II核心(Os_core)块

    /*************************************************************************************************** ...

  10. Runner站立会议03

    开会时间:21.10~21.30 地点:二教103 今天做了什么:Android的存储,只是存储在/date/date 文件夹下和sd卡 明天准备做什么:学习Android的数据库的使用sqlite ...