hdu4003 树形dp+分组背包

      题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4003

     题意:给定一棵n个结点的树及树根,树的每条路径有一个权值,现在树根上有k个机器人,用这k个机器人遍历这棵树,求机器人走的权值之和的最小值。

     树形dp的题目还是做的太少了。

     我们用f[i][j]表示在以i为根的子树里有j个机器人遍历这棵子树权值之和的最小值,特别的,我们用f[i][0]表示用一个机器人走完以i为根的子树并且这个机器人又回到i所走的权值和。

    那么,显然我们可以得到f[i][0]=∑(f[each son of i ][0]+2*weight[i][each son of i])

    假设结点x有i个儿子,那么对于每一个儿子i有f[i][0],f[i][1]……f[i][k]共k+1种状态,那么我们可以把每个儿子分成一组,i个儿子即为i组,对于每一组含有k+个有价值的物品,这样我们就把它近似的抽象成了一个分组背包的问题,也就是说,f[x][j]是由x的每个儿子中选择一个物品更新而来的。

   这里和分组背包的不同点在于:分组背包要求每组物品至多选择一个,而这道题要求每一组必须选择一个物品。所以我们开始的时候将f[x][j]初始化为f[son][0]+2*weight[x][son],然后找到比当前f[x][j]值小的解时更新,这样可以保证一定会选择一组。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>

using namespace std;

struct node
{
    int x,w,next;
};

int len;
int n,s,k;
node tree[20005];
int head[10005];
int f[10005][13];

void add(int a,int b, int c)
{
    tree[len].x=b; tree[len].w=c;
    tree[len].next=head[a];
    head[a]=len; len++;
}

void dfs(int s,int p)
{
    for (int i=head[s];i!=-1;i=tree[i].next)
    {
        int x=tree[i].x;
        if (x==p) continue;
        dfs(x,s);
        for (int j=k;j>=0;j--)
        {
            f[s][j]+=f[x][0]+2*tree[i].w;
            for (int l=1;l<=j;l++)
                f[s][j]=min(f[s][j],f[s][j-l]+f[x][l]+l*tree[i].w);
        }
    }
}

int main()
{
    while (scanf("%d%d%d",&n,&s,&k)!=EOF)
    {
        memset(head,-1,sizeof(head));
        memset(f,0,sizeof(f));
        len=0;
        for (int i=0;i<n-1;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c); add(b,a,c);
        }
        dfs(s,-1);
        printf("%d\n",f[s][k]);
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值