hdu4003(树形dp)

来源:互联网 发布:数据修炼系统 编辑:程序博客网 时间:2024/05/29 15:44

链接:点击打开链接

题意:一棵N个节点的树,每条边都有一个权值,K个机器人从S点出发,问让机器人遍历所有边,最少花费值是多少

代码:

#include <vector>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;int N,S,K;int dp[10005][15],used[10005];                  //dp[i][j]代表以i为根节点的子树花费struct node{                                    //j个机器人遍历的最少花费    int to,cost;};vector<node> G[10005];void dfs(int s){    int i,j,k,tmp;    used[s]=1;    for(i=0;i<G[s].size();i++){        tmp=G[s][i].to;        if(G[tmp].size()&&!used[tmp]){            dfs(tmp);            for(j=K;j>=0;j--){                  //将一个机器人遍历以s为节点的树作为初始值            dp[s][j]+=(dp[tmp][0]+2*G[s][i].cost);            for(k=1;k<=j;k++)            dp[s][j]=min(dp[s][j],dp[s][j-k]+dp[tmp][k]+k*G[s][i].cost);            }                                   //树形dp        }    }}int main(){    int i,j,a,b,w;    while(scanf("%d%d%d",&N,&S,&K)!=EOF){        for(i=1;i<=N;i++)        G[i].clear();        memset(dp,0,sizeof(dp));        memset(used,0,sizeof(used));        for(i=0;i<N-1;i++){            scanf("%d%d%d",&a,&b,&w);            G[a].push_back((node){b,w});            G[b].push_back((node){a,w});        }        dfs(S);        printf("%d\n",dp[S][K]);    }    return 0;}


 

0 0
原创粉丝点击