Ural-1018-Binary Apple Tree

来源:互联网 发布:win qt 串口编程 编辑:程序博客网 时间:2024/04/27 21:25

树形DP的一个题,题意是说给你一些树枝,树枝上面有苹果,现在要求你保留其中的Q个,使得苹果树最多,问最多能留住多少个苹果。

对于每个分支结点来说,有三种选择:

1、减去左子树

2、减去右子树

3、将节点数合理分配给左右子树


代码:

#include<cstdio>#include<cstring>#include<iostream>using namespace std;const int maxn=300;int e,n,q,pnt[maxn],nxt[maxn],cost[maxn],head[maxn],w[maxn],lch[maxn],rch[maxn],dp[maxn][maxn];void AddEdge(int u,int v,int c){    pnt[e]=v;nxt[e]=head[u];cost[e]=c;head[u]=e++;}void DFS(int u,int f){    for(int i=head[u];i!=-1;i=nxt[i])if(pnt[i]!=f){    if(!lch[u])lch[u]=pnt[i];    elserch[u]=pnt[i];    w[pnt[i]]=cost[i];    DFS(pnt[i],u);}}int DP(int x,int k){    if(!k)return 0;    if(dp[x][k]>=0)return dp[x][k];    if(!lch[x])return dp[x][k]=w[x];    for(int i=0;i<k;i++)dp[x][k]=max(dp[x][k],DP(lch[x],i)+DP(rch[x],k-i-1));    dp[x][k]+=w[x];    return dp[x][k];}int main(){    while(scanf("%d%d",&n,&q)!=EOF)    {e=0;memset(head,-1,sizeof(head));memset(lch,0,sizeof(lch));memset(rch,0,sizeof(rch));memset(dp,255,sizeof(dp));for(int i=1;i<n;i++){    int u,v,c;    scanf("%d%d%d",&u,&v,&c);    AddEdge(u,v,c);    AddEdge(v,u,c);}DFS(1,-1);printf("%d\n",DP(1,q+1));    }    return 0;}


原创粉丝点击