• 1947Rebuilding Roads


    大神的题解

    题意:给一个包含n个节点的树,然后让你找一颗节点数为p的子树,同时让你删掉最少数目的边把这个子树给孤立起来,问这个最少的边数。

    思路:很容易想到要用到01背包,要把子树的情况进行背包。用dp[root][j]记录 以root为根的、节点数为j的子树的孤立起来需要删除的最少的边数。

    状态方程为:dp[root][p]=min(dp[root][p],  dp[u][k]+dp[root][p-k]-2);(其中u为root的一个孩子)

    由于u与root之间的边连接了起来,所以dp[u][k]+dp[root][p-k] 多加了2次他们之间的边,所以要减去2;

    含义是:我们把以 root 为根的节点的子树,把每一个分支作为背包的物品,决策就是每一个分支的选与不选,
    而对于每一个分支的状态其实就是该问题的一个子问题,然后这样分割成 2 块后,我们会发现多砍了该节点与子节点的边两次,要减去之;
    代码:
    # include<stdio.h>
    # include<string.h>
    # define N 155 
    int n,p;
    struct node{
        int from,to,next;
    }edge[2*N];
    int head[N],tol,ans[N],dp[N][N];
    void add(int a,int b)
    {
        edge[tol].from=a;edge[tol].to=b;edge[tol].next=head[a];head[a]=tol++;
    }
    int min(int a,int b)
    {
        return a<b?a:b;
    }
    void dfs(int root,int father)
    {
        int i,j,k,u;
        for(i=head[root];i!=-1;i=edge[i].next)
        {
            u=edge[i].to;
            if(u!=father) dfs(u,root);
        }
        for(i=head[root];i!=-1;i=edge[i].next)
        {
            u=edge[i].to;
            if(u==father) continue;
            for(j=p;j>1;j--)
            {
                for(k=1;k<j;k++)
                    dp[root][j]=min(dp[root][j],dp[u][k]+dp[root][j-k]-2);//子树和父亲节点之间的边多加了两次,所以要减去
            }
        }
    }
    int main()
    {
        int i,j,a,b,Min;
        while(scanf("%d%d",&n,&p)!=EOF)
        {
        memset(head,-1,sizeof(head));
        memset(ans,0,sizeof(ans));
        tol=0;
        for(i=1;i<n;i++)
        {
            scanf("%d%d",&a,&b);
            add(a,b);
            add(b,a);
            ans[a]++;
            ans[b]++;
        }
        for(i=1;i<=n;i++)
            for(j=1;j<=p;j++)
                dp[i][j]=N;
        for(i=1;i<=n;i++)
            dp[i][1]=ans[i];
        if(n==p) printf("0
    ");
        else
        {
            dfs(1,0);
            Min=N;
            for(i=1;i<=n;i++)
                Min=min(Min,dp[i][p]);
            printf("%d
    ",Min);
        }
        }
        return 0;
    }
  • 相关阅读:
    [转]org.apache.poi3.1.7 Excle并发批量导入导出,格式设置方式需要修改
    [转]POI使用HSSF,XSSF,SXSSF三种方式
    [转]idea maven项目dependencies红线 解决办法
    mysqlGTID主从同步出现1236错误问题
    MySQL日志:slow query log
    telnet 去掉用户名和密码
    [PHP] 装饰器模式-结构型设计模式
    [GO] 变参函数-GO中函数传递变长参数
    [PHP] 数据映射器模式-结构型设计模式
    [GO-FLY] GO-FLY客服实现浏览器消息提示音
  • 原文地址:https://www.cnblogs.com/dowson/p/3334277.html
Copyright © 2020-2023  润新知