J - Find Metal Mineral HDU - 树形DP+背包

  • J - Find Metal Mineral

  •  HDU - 4003 
  • 题意:k个机器人到S点,问机器人找完所有金矿后,最短的移动距离;如果只有一个机器人,
  • 他就要找遍所有金矿就会走重复的路,直到找到最后一个矿;如果有两个机器人,他俩就可以分头行动;
  • 思路:dp[i][j]=min(dp[i][j-k]+dp[son][k] | 0<=k<=j)设dp[i][j]表示i节点分配j个机器人的最短移动距离
  • 0并不表示不分配机器人了,而是只有一个机器人分配过来,并且最终返回父节点;
  • #include<bits/stdc++.h>
    using namespace std;
    #define inf 0x3f3f3f3f
    #define maxn 10086
    int n,k,s,x,y,z;
    int head[maxn],tot;
    int dp[maxn][15];
    struct node
    {
        int v,w,to;
    } edge[maxn*2];
    void add(int x,int y,int z)
    {
        edge[++tot].v=y;
        edge[tot].w=z;
        edge[tot].to=head[x];
        head[x]=tot;
        edge[++tot].v=x;
        edge[tot].w=z;
        edge[tot].to=head[y];
        head[y]=tot;
    }
    void dfs(int root,int pre)
    {
        for(int i=head[root]; i!=-1; i=edge[i].to)
        {
            int son=edge[i].v;
            int dis=edge[i].w;
            if(son==pre)continue;
            dfs(son,root);
            for(int j=k; j>=0; j--)
            {
                dp[root][j]+=dp[son][0]+dis*2;
                for(int p=1; p<=j; p++)
                    dp[root][j]=min(dp[root][j],dp[root][j-p]+dp[son][p]+dis*p);
            }
        }
    }
    int main()
    {
        while(~scanf("%d%d%d",&n,&s,&k))
        {
            tot=0;
            memset(head,-1,sizeof(head));
            memset(dp,0,sizeof(dp));
            for(int i=1; i<n; i++)
            {
                scanf("%d%d%d",&x,&y,&z);
                add(x,y,z);
            }
            dfs(s,s);
            printf("%d\n",dp[s][k]);
        }
        return 0;
    }
  •  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值