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 )
  • 相关阅读:
    mysql慢查询
    linux查找文件
    ss安装教程
    node_module删除
    api的错误代码设计
    es6的Promise
    vue后台项目
    vue的main.js
    vue的过渡效果
    【Linux网络基础】网络拓扑、OSI层次模型、TCP/IP协议簇
  • 原文地址:https://www.cnblogs.com/CKboss/p/3350821.html
Copyright © 2011-2022 走看看