您的位置:首页 > 移动开发

Ural-1018 Binary Apple Tree(树形dp+分组背包)

2013-09-13 21:37 232 查看
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

const int maxn = 100;
int dp[maxn][maxn]; //dp[i][j]表示以i为根,保留j个点的最大权值。
int N,Q;
int G[maxn][maxn];
int num[maxn];   //以i为根的树的节点个数。

//这里处理的时候要注意可以把边的权值压倒儿子节点。
void dfs(int u,int fa){
num[u] = 1;
for(int v=1;v<=N;v++){
if(!G[u][v] || v == fa)  continue;

dfs(v,u);
num[u] += num[v];
}

for(int v=1;v<=N;v++){    //相当于分组k。
if(!G[u][v] || v == fa)  continue;

for(int i=num[u];i>0;i--){     //相对于下面的V -> 0
for(int j=1;j<i&&j<=num[v];j++)    //枚举组k中的元素。
dp[u][i] = max(dp[u][i],dp[u][i-j]+dp[v][j]+G[u][v]);
}
}
}
/**
f[k][v]表示前k组物品花费费用v能取得的最大权值
f[k][v]=max{f[k-1][v],f[k-1][v-c[i]]+w[i]|物品i属于组k}
分组背包一维数组的伪代码:
for 所有的组k
for v=V..0
for 所有的i属于组k
f[v]=max{f[v],f[v-c[i]]+w[i]}
**/
int main()
{
cin>>N>>Q;
memset(G,0,sizeof(G));
memset(dp,0,sizeof(dp));
for(int i=1;i<N;i++){
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
G[u][v] = G[v][u] = w;
}
dfs(1,-1);
printf("%d\n",dp[1][Q+1]);
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: