hdu4003Find Metal Mineral 树形dp+分组背包

来源:互联网 发布:机智证券交易软件诈骗 编辑:程序博客网 时间:2024/04/26 20:00
//k个机器人从一颗树的树根开始往下走,//走树的每条边都要消耗能量,问这k个人最少花多少能量能遍历所有点//dp[u][i] 表示以u点为根节点的子树用i个节点遍历最少需要多少能量//当i = 0时表示有一个点遍历了这颗子树又返回上一个节点#include<cstdio>#include<cstring>#include<iostream>#include<vector>using namespace std ;const int maxn = 10010 ;const int inf = 0x3f3f3f3f;int dp[maxn][60] ;int head[maxn] ;int nedge ;int n , s , m;struct Edge{    int v , w ;    int next ;}edge[maxn<<1] ;void addedge(int u , int v , int w){    edge[nedge].v = v ;    edge[nedge].w = w;    edge[nedge].next = head[u] ;    head[u] = nedge++;}void dfs(int u , int pre){    int flag = 0 ;    for(int i = head[u] ;i != -1 ;i =edge[i].next)    {        int v = edge[i].v ;        if(v == pre)continue ;        dfs(v , u) ;        int len = edge[i].w ;        for(int j = m;j >= 0;j--)        {            int sum = inf ;            for(int k = 0;k <= j;k++)            {                int tmp = (k == 0 ? 2*len : k*len);                sum = min(sum , dp[u][j-k] + dp[v][k] + tmp) ;            }            dp[u][j] = sum;        }    }}int main(){  //freopen("in.txt" ,"r" , stdin) ;    while(~scanf("%d%d%d" ,&n , &s , &m))    {        memset(head , -1 , sizeof(head)) ;        memset(dp , 0 ,sizeof(dp)) ;        nedge = 0 ;        for(int i = 1;i < n;i++)        {            int u , v , w ;            scanf("%d%d%d" , &u , &v , &w) ;            addedge(u , v , w) ;            addedge(v , u , w) ;        }        dfs(s,0) ;        cout<<dp[s][m]<<endl;    }    return 0 ;}
0 0
原创粉丝点击