码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 1249 F. Maximum Weight Subset

时间:2019-10-29 09:56:52      阅读:86      评论:0      收藏:0      [点我收藏+]

标签:不能   set   ems   eof   title   ble   表示   def   合并   

传送门

设 $f[x][i]$ 表示 $x$ 的子树中,离 $x$ 最近的选择的节点距离为 $i$ 的合法方案的最大价值

设 $val[x]$ 表示节点 $x$ 的价值,首先有 $f[x][0]=val[x]$

那么考虑子树的合并,有 $f[x][min(i,j+1)]=max(f[x][min(i,j+1)],f[x][i]+f[v][j])$

注意此时 $f[x][i]$ 不能包括 $v$ 的贡献,这个可以搞个 $tmp$ 存一下新的 $f[x]$,最后统一覆盖掉即可

然后答案就是 $f[rt]$ 里面的状态取个最大值

复杂度 $n^3$

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<0||ch>9) { if(ch==-) f=-1; ch=getchar(); }
    while(ch>=0&&ch<=9) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
const int N=207;
int n,m,val[N];
int fir[N],from[N<<1],to[N<<1],cntt;
inline void add(int a,int b) { from[++cntt]=fir[a]; fir[a]=cntt; to[cntt]=b; }
int f[N][N],tmp[N],ans;
vector <int> son[N];
void dfs(int x,int fa)
{
    f[x][0]=val[x];
    for(int i=fir[x];i;i=from[i])
    {
        int &v=to[i]; if(v==fa) continue;
        dfs(v,x); memset(tmp,0,sizeof(tmp));
        for(int j=0;j<=n;j++)
            for(int k=0;k<=n;k++)
                if(j+k+1>m) tmp[min(j,k+1)]=max(tmp[min(j,k+1)],f[x][j]+f[v][k]);
        for(int j=0;j<=n;j++) f[x][j]=tmp[j];
    }
}
int main()
{
    n=read(),m=read(); int a,b;
    for(int i=1;i<=n;i++) val[i]=read();
    if(n==1) { printf("%d\n",val[1]); return 0; }
    for(int i=1;i<n;i++)
        a=read(),b=read(),
        add(a,b),add(b,a);
    dfs(1,0);
    for(int i=0;i<=n;i++) ans=max(ans,f[1][i]);
    printf("%d\n",ans);
    return 0;
}

 

Codeforces 1249 F. Maximum Weight Subset

标签:不能   set   ems   eof   title   ble   表示   def   合并   

原文地址:https://www.cnblogs.com/LLTYYC/p/11756634.html

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