首页 > 其他分享 >P4657 Chase

P4657 Chase

时间:2022-10-01 17:23:29浏览次数:33  
标签:P4657 res ll fa maxn max tmp2 Chase

一种和其他题解不同的dp定义

发现其他题解是四倍空间 选和不选 最大次大

因为比较恶心 所以我们考虑直接强制这个点不选

当其他点dp到它时再考虑它自己

码量很小 也简洁易懂

注意当\(i\)的值由\(i-1\)的值转移过来时还要判断\(i-1\)的值是用最大值转移还是次大值转移

换根一共四种情况

设可以用来更新的值为\(tmp\) 选上父节点的贡献为\(res\)

1 \(tmp=max(f[fa[u]][i],f[fa[u]][i−1]+res)\)(\(i\)处最大值 \(i-1\)处最大值都不来源于\(u\))

2 \(tmp=max(f[fa[u]][i],g[fa[u]][i−1]+res)\)(剩下三种同理)

3 \(tmp=max(g[fa[u]][i],f[fa[u]][i−1]+res)\)

4 \(tmp2=max(g[fa[u]][i],g[fa[u]][i−1]+res)\)

注意特判\(0\)下标 否则\(i-1\)会访问负下标

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#define Sakura int
#define Re register ll
#define _ putchar(' ')
#define el putchar('\n')
#define ll long long

using namespace std;

const ll maxn=1e5+10;

inline ll read(){
    ll x=0,f=0;char c=getchar();
    while(!isdigit(c)) f|=c=='-',c=getchar();
    while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return f?-x:x;
}

inline void ot(ll x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) ot(x/10);putchar(x%10|48);
}

vector<ll> G[maxn];
ll n,m;
ll a[maxn];
ll f[maxn][110],g[maxn][110];
ll tmp1[110];
ll fa[maxn];
ll sum[maxn];
ll ans;

void dfs1(ll u){
    for(auto v:G[u]){
        if(v==fa[u]) continue;
        fa[v]=u;
        sum[u]+=a[v];
        dfs1(v);
        for(Re i=1;i<=m;++i){
            ll tmp=max(f[v][i],f[v][i-1]+sum[v]);
            if(tmp>=f[u][i]){
                g[u][i]=f[u][i];
                f[u][i]=tmp;
            }
            else g[u][i]=max(g[u][i],tmp);
        }
    }
}

void dfs2(ll u){
    if(fa[u]){
        ll res=sum[fa[u]]-a[u]+a[fa[fa[u]]];
        for(Re i=1;i<=m;++i) tmp1[i]=max(f[u][i],f[u][i-1]+sum[u]);
        for(Re i=1;i<=m;++i){
            ll tmp2;
            if(g[fa[u]][i]>=tmp1[i]) 
                if(g[fa[u]][i-1]>=tmp1[i-1]) tmp2=max(f[fa[u]][i],f[fa[u]][i-1]+res);
                else tmp2=max(f[fa[u]][i],g[fa[u]][i-1]+res);
            else 
                if(g[fa[u]][i-1]>=tmp1[i-1]) tmp2=max(g[fa[u]][i],f[fa[u]][i-1]+res);
                else tmp2=max(g[fa[u]][i],g[fa[u]][i-1]+res);
            if(tmp2>=f[u][i]){
                g[u][i]=f[u][i];
                f[u][i]=tmp2;
            }
            else g[u][i]=max(g[u][i],tmp2);
        }
    }
    ans=max(ans,max(f[u][m],f[u][m-1]+sum[u]+a[fa[u]]));
    for(auto v:G[u]) if(v!=fa[u]) dfs2(v);
}

Sakura main(){
    n=read(),m=read();
    if(!m){
        puts("0");
        return 0;
    }
    for(Re i=1;i<=n;++i) a[i]=read();
    for(Re i=1;i<n;++i){
        ll x=read(),y=read();
        G[x].push_back(y);
        G[y].push_back(x);
    }
    dfs1(1);
    dfs2(1);
    ot(ans);
}

标签:P4657,res,ll,fa,maxn,max,tmp2,Chase
From: https://www.cnblogs.com/Sakura-Lu/p/16747440.html

相关文章