• 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 )
  • 相关阅读:
    == 与 equals 之区别
    值传递和引用传递
    try-catch-finally容易犯的错误
    设计模式之备忘录模式
    设计模式之观察者模式 Observer
    设计模式之状态模式 State
    设计模式之模板方法模式 templateMethod
    设计模式之策略模式 Strategy
    Java过滤器与SpringMVC拦截器之间的关系与区别
    SpringMVC中使用Interceptor拦截器
  • 原文地址:https://www.cnblogs.com/CKboss/p/3350821.html
Copyright © 2020-2023  润新知