zoukankan      html  css  js  c++  java
  • HDOJ 4003 Find Metal Mineral (树DP)

    题意:给定一棵树,边权表示通过此边的代价,给k个机器人,指定从点s出发,求遍历所有结点的最小代价和。

    分析:设计状态时不难想到用dp[i][j]表示从结点 i 出发遍历以它为根的子树的最小代价,但是转移时就遇到麻烦了,考虑只给你 1 个机器人的时候,这时要遍历所有结点就必然要走回头路,如果我们对每个结点再增加一个信息,表示从 i 出发遍历以 i 为根的子树且最后回到 i 的最小代价,这样转移就好办了,对于每个结点,将 j 个机器人分配给它的所有子结点,若分配 0 个机器人,则表明要派一个机器人去,遍历完了又回到 i 。方便起见,就以dp[i][0]表示从 i 出发遍历完子树 i 又回到i的最小代价。

    View Code
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 10010
    #define M 11
    int n,e,s,m;
    int first[N],next[N<<1],v[N<<1],w[N<<1],d[N];
    int dp[N][M];
    void init()
    {
        e=0;
        memset(first,-1,sizeof(first));
        memset(d,0,sizeof(d));
        memset(dp,0,sizeof(dp));
    }
    void add(int a,int b,int c)
    {
        d[a]++;
        v[e]=b;
        w[e]=c;
        next[e]=first[a];
        first[a]=e++;
    }
    void dfs(int a,int fa)
    {
        if(d[a]==1 && v[first[a]]==fa)  return;
        int i,j,k,b;
        for(i=first[a];~i;i=next[i])
        {
            b=v[i];
            if(b==fa)   continue;
            dfs(b,a);
            for(j=m;j>=0;j--)
            {
                dp[a][j]+=dp[b][0]+2*w[i];
                for(k=1;k<=j;k++)
                {
                    dp[a][j]=min(dp[a][j],dp[a][j-k]+dp[b][k]+k*w[i]);
                }
            }
        }
    }
    int main()
    {
        int a,b,c;
        while(~scanf("%d%d%d",&n,&s,&m))
        {
            init();
            for(int i=1;i<n;i++)
            {
                scanf("%d%d%d",&a,&b,&c);
                add(a,b,c);
                add(b,a,c);
            }
            dfs(s,0);
            printf("%d\n",dp[s][m]);
        }
        return 0;
    }
  • 相关阅读:
    第二章 课后习题 6
    第二章 课后习题 5
    第一章 课后习题 10
    第一章 课后习题 7
    JAVA练习1
    作业2
    作业
    c++作业10月13日作业
    c++作业50页例题3.1
    for循环作业4和5
  • 原文地址:https://www.cnblogs.com/algorithms/p/2689010.html
Copyright © 2011-2022 走看看