URAL 1018 Binary Apple Tree 简单树形背包

来源:互联网 发布:模块数据出现异常 编辑:程序博客网 时间:2024/05/14 09:32

点击打开链接

题意:n个结点的树,每条边都有边权,问保留根节点1和Q条边时,最大的边权和是多少?

保留Q条边 即保留Q+1个点,dp[i][j] 以i为根的子树中选j个的最大价值 

dp[i][j]=max(dp[i][j],dp[v][k]+dp[i][j-k])
递推时,dp[i][j-k]为不含子树v,选j-k的最大价值 

#include <bits/stdc++.h>using namespace std;typedef pair<int,int> pii;const int N=2e3+20;int n,q,sz[N];vector<pii> e[N];int dp[N][N];//int dfs_size(int u,int fa){sz[u]=1;for(int i=0;i<e[u].size();i++){int v=e[u][i].first;if(v==fa) continue;dfs_size(v,u);sz[u]+=sz[v];}return sz[u];}void dfs(int u,int fa){int v,w;for(int i=0;i<e[u].size();i++){v=e[u][i].first,w=e[u][i].second;if(v==fa) continue;dfs(v,u);for(int j=sz[u];j>1;j--)//{for(int k=1;k<j;k++){//选v则边(u,v)被选 dp[u][j]=max(dp[u][j],dp[v][k]+dp[u][j-k]+w);//dp[u][j-k]为不含子树v,选j-k的最大价值 }} }}int main(){while(cin>>n>>q){memset(sz,0,sizeof(sz));for(int i=1;i<=n;i++)e[i].clear();int u,v,w;for(int i=1;i<=n-1;i++){cin>>u>>v>>w;e[u].push_back(pii(v,w));e[v].push_back(pii(u,w));}dfs_size(1,-1);dfs(1,-1);cout<<dp[1][q+1]<<endl; }return 0;}


0 0
原创粉丝点击