hdoj4003 (dp + tree packet backpack)

Topic link: https: //vjudge.net/problem/HDU-4003

Meaning of the title: the right side to a tree, the roots have a m s personal, to traverse through all the points m individual, a person after spending an edge to edge weights, find the minimum cost (you can take the edge has gone ).

Ideas:

  Comparative miss state, with DP [u] [j] represents a j with a minimum cost of individual nodes in the subtree of u. But transfer equation a bit difficult to think.

  It is important how to deal dp [u] [0], to dp [v] [0], 0 minimum cost that is personal in the sub-tree node v, then u can only come through a robot parent node of v , it is assumed x person, that this individual x u have to return to the job after traversing all points v subtree, then the cost is 2 * sum [v] + 2k * w, sum [v] is all v subtree and edge weights, w is u-> v edge weight, so that it takes a minimum when k =, to take 2 * sum [v] + 2 * w. Therefore dp [u] [0] = sum (2 * sum [v], 2 * w), the sum represents the sum outside.

  that j> 0, simply Release: dp [u] [j] = min (dp [u] [j], dp [u] [jk] + dp [v] [k] + k * w), v u is a child node, k v represents a child node of k individuals, w is u-> v of the right side.

AC Code:

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=1e4+5;
const int inf=0x3f3f3f3f;
int n,s,m,cnt,head[maxn],sum[maxn],dp[maxn][15];

struct node{
    int v,w,nex;
}edge[maxn<<1];

void adde(int u,int v,int w){
    edge[++cnt].v=v;
    edge[cnt].w=w;
    edge[cnt].nex=head[u];
    head[u]=cnt;
}

void dfs(int u,int fa){
    for(int i=head[u];i;i=edge[i].nex){
        int v=edge[i].v;
        if(v==fa) continue;
        dfs(v,u);
        for(int j=m;j>=0;--j)
            for(int k=0;k<=j;++k)
                if(k) dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v][k]+k*edge[i].w);
                else dp[u][j]+=dp[v][0]+2*edge[i].w;
    }
}

int main(){    
    while(~scanf("%d%d%d",&n,&s,&m)){
        cnt=0;
        for(int i=1;i<=n;++i){
            head[i]=0;
            for(int j=0;j<=m;++j)
                dp[i][j]=0;
        }
        for(int i=1;i<n;++i){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            adde(u,v,w);
            adde(v,u,w);
        }
        dfs(s,0);
        printf("%d\n",dp[s][m]);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/FrankChen831X/p/11458658.html