树形dp ural1018苹果二叉树

来源:互联网 发布:优化手机相机 编辑:程序博客网 时间:2024/05/22 18:56
#include<iostream>#include<vector>#include<string>#include<queue>#include<cstdio>#include<cstring>#define maxn 200#define INF 0xfffffffusing namespace std;int dp[maxn][maxn];//dp[i][j]表示以i为根取j条树枝的最大值//1.只有一个子树//dp[i][j]=max(dp[child][j-1]+val[i][child]);//2.有两个子树//dp[i][j]=max(dp[child1][k]+dp[child2][j-k-2])  0<=k<=j-2;//这里采用记忆化搜索,记录所有可能的状态,因为点还是比较少的。//一般的树形dp是先求出子树的状态,再根据子树的状态去得出根的状态,这有明显的层次结构的。int n,m;vector<int> g[maxn];//因为要判断每棵树的子树个数,所以用vector比较好用int map[maxn][maxn],vis[maxn];void init(){    for(int i=1; i<=n; i++)    {        g[i].clear();    }    memset(vis,0,sizeof(vis));    memset(dp,0,sizeof(dp));    memset(map,0,sizeof(dp));}int dfs(int u,int q,int f){    vis[u]=1;    int size=g[u].size();    if(size==0||q<=0||(size==1&&f!=-1))//只有一个点,不可以摘,叶子节点    {        return 0;    //叶子节点或者不能摘结束    }    if(dp[u][q]!=0) return dp[u][q];    //cout<<u<<' '<<v[1]<<' '<<v[2]<<' ';    //int v1=g[u][0],v2=g[u][1];    /*    2 2    1 2 10    */    if((g[u].size()==2&&f!=-1)||(g[u].size()==1&&f==-1))    {        //cout<<"yes"<<endl;        int v=g[u][0];        if(v==f)        v=g[u][1];        dp[u][q]=max(dp[u][q],dfs(v,q-1,u)+map[u][v]);//只有一棵子树        //cout<<u<<' '<<q<<' '<<dp[u][q]<<endl;    }    else    {        int v[5],cnt=0;        for(int i=0; i<size; i++) //找出子树结点        {            if(g[u][i]!=f)            {                v[++cnt]=g[u][i];            }        }        dp[u][q]=max(dp[u][q],dfs(v[1],q-1,u)+map[u][v[1]]);//只取第一棵子树        //cout<<dfs(v[1],q-1)+map[u][v[1]]<<' ';        dp[u][q]=max(dp[u][q],dfs(v[2],q-1,u)+map[u][v[2]]);//只取第二棵子树        //cout<<dfs(v[2],q-1)+map[u][v[2]]<<endl;        for(int k=0; k<q-1; k++) //两棵树的边都取        {            dp[u][q]=max(dp[u][q],dfs(v[1],k,u)+map[u][v[1]]+dfs(v[2],q-k-2,u)+map[u][v[2]]);        }    }    //cout<<dp[u][q]<<endl;    return dp[u][q];}int main(){    int u,v,val,i,j,k;    while(cin>>n>>m)    {        init();        for(int i=1; i<n; i++)        {            cin>>u>>v>>val;            g[u].push_back(v);            g[v].push_back(u);            map[u][v]=val;            map[v][u]=val;        }        dfs(1,m,-1);        cout<<dp[1][m]<<endl;    }    return 0;}

原创粉丝点击