码迷,mamicode.com
首页 > 移动开发 > 详细

P2015 二叉苹果树

时间:2019-07-23 15:09:47      阅读:101      评论:0      收藏:0      [点我收藏+]

标签:stream   dfs   pac   min   表示   max   void   ios   ring   

题面:https://www.luogu.org/problemnew/show/P2015

设f[u][i]表示u的子树上保留i条边,至多保留的苹果数目
那么状态转移方程也就显而易见了:
f[u][i]=max(f[u][i],f[u][i?j?1]+f[v][j]+e[i].w)( 1≤i≤min(q,sz[u]),0≤j≤min(sz[v],i?1))
u表示当前节点,v是u的一个子节点,sz[u]表示u的子树上的边数,q就是题目中要求的最多保留边数。

Code:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<ctime>
#include<vector>
using namespace std;
const int N=105;
vector<int>a[N];
int n,q,f[N][N],val[N][N];
bool vis[N];
void dfs(int u){
    if(!vis[u]){
        vis[u]=1;
    }
    int length=a[u].size();
    for(int i=0;i<length;i++){
        int v=a[u][i];
        if(!vis[v]){
            vis[v]=1;
            dfs(v);
            for(int j=q;j>=1;j--){
                for(int k=j-1;k>=0;k--){
                    f[u][j]=max(f[u][j],val[u][v]+f[v][k]+f[u][j-k-1]);
                }
            }
        }
    }
}
int main(){
    int u,v,w;
    scanf("%d%d",&n,&q);
    for(int i=1;i<n;i++){
        scanf("%d%d%d",&u,&v,&w);
        val[u][v]=w;
        a[u].push_back(v);
    }
    dfs(1);
    printf("%d\n",f[1][q]);
    return 0;
}

P2015 二叉苹果树

标签:stream   dfs   pac   min   表示   max   void   ios   ring   

原文地址:https://www.cnblogs.com/ukcxrtjr/p/11231488.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!