• 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 )
  • 相关阅读:
    PL/SQL会遇到中文插入乱码问题、数据显示不全
    PL/SQL数据生成器
    编程小案例
    MySql案例收集
    关于PL/SQL的安装配置
    Android 歌词桌面同步显示
    DataGridView控件使用大全
    flex java 交互
    Android Launcher 全面剖析
    Android adb 命令
  • 原文地址:https://www.cnblogs.com/CKboss/p/3350821.html
Copyright © 2020-2023  润新知