zoukankan      html  css  js  c++  java
  • POJ 1947 Rebuilding Roads


    树形DP。。。。。
    Rebuilding Roads
    Time Limit: 1000MSMemory Limit: 30000K
    Total Submissions: 8188Accepted: 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 ",ans);
        }
        return 0;
    }
    * This source code was highlighted by YcdoiT. ( style: Codeblocks )
  • 相关阅读:
    pip 安装用 国内清华大学的数据源
    sql server 中导出图片并命名
    金跌 K3 科目表
    SQLSERVER 循环
    语句判断记录是否存在(最简洁简单性能最优)
    增、删、改开放时间表时,同步数据至 CP
    [网络流24题] 圆桌问题(最大流)
    [网络流24题] 最小路径覆盖问题(匈牙利 最大流)
    C. Vasya And Array (贪心构造)
    【牛客网】一个有意思的前缀和题目
  • 原文地址:https://www.cnblogs.com/CKboss/p/3350821.html
Copyright © 2011-2022 走看看