其他分享
首页 > 其他分享> > Luogu4383 [八省联考2018]林克卡特树

Luogu4383 [八省联考2018]林克卡特树

作者:互联网

https://www.luogu.com.cn/problem/P4383

\(wqs\)二分/树型\(DP\)

可以看到,题目本质上要求的是取\(k+1\)条链,使其边权和最大

先打一个树型\(DP\)(够头疼的了)

\(dp_{i,j,0/1/2}\),\(i\)表示哪一个节点,\(j\)表示已经用了几条链了,\(0/1/2\)代表的是一个节点的度数,注意,当度数为\(1\)时,我们不计算该条链的贡献(因为可能与其他链拼接)

注意,一个点也可以作为一条链,我们直接初始化\(dp_{i,1,2}=0\),表示该点单独取

此外,\(dp_{i,0,0}=0\)(不取,显然),其他位置的权值都为\(-INF\)

#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
#define N 600005
#define INF 12345678987654321
using namespace std;
int tot,head[N],nxt[N],d1[N],d2[N],n,k,x,y,z;
ll ans,dp[N >> 1][105][3],kz[105][3];
void add(int x,int y,int z)
{
    tot++;
    d1[tot]=y,d2[tot]=z;
    nxt[tot]=head[x];
    head[x]=tot;
}
void ckmx(ll &x,ll y)
{
    if (x<y)
        x=y;
}
void dfs(int u,int f)
{
    for (int i=head[u];i;i=nxt[i])
    {
        int v=d1[i];
        int cost=d2[i];
        if (v==f)
            continue;
        dfs(v,u);
        for (int t=0;t<=k;t++)
            for (int q=0;q<3;q++)
                kz[t][q]=dp[u][t][q];
        for (int t=k;t>=0;t--)
        {
            for (int q=0;q<=t;q++)
            {
                ckmx(dp[u][t][0],dp[v][q][0]+kz[t-q][0]);
                if (t>q)
                    ckmx(dp[u][t][0],dp[v][q][1]+kz[t-q-1][0]);
                ckmx(dp[u][t][0],dp[v][q][2]+kz[t-q][0]);
                ckmx(dp[u][t][1],dp[v][q][0]+kz[t-q][1]);
                ckmx(dp[u][t][1],dp[v][q][0]+kz[t-q][0]+cost);
                if (t>q)
                    ckmx(dp[u][t][1],dp[v][q][1]+kz[t-q-1][1]);
                ckmx(dp[u][t][1],dp[v][q][1]+kz[t-q][0]+cost);
                ckmx(dp[u][t][1],dp[v][q][2]+kz[t-q][1]);
                ckmx(dp[u][t][2],dp[v][q][0]+kz[t-q][2]);
                if (t>q)
                    ckmx(dp[u][t][2],dp[v][q][0]+kz[t-q-1][1]+cost);
                if (t>q)
                    ckmx(dp[u][t][2],dp[v][q][1]+kz[t-q-1][2]);
                if (t>q)
                    ckmx(dp[u][t][2],dp[v][q][1]+kz[t-q-1][1]+cost);
                ckmx(dp[u][t][2],dp[v][q][2]+kz[t-q][2]);
            }
        }
    }
}
int main()
{
    scanf("%d%d",&n,&k),k++;
    for (int i=1;i<n;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    for (int i=0;i<=n;i++)
    {
        for (int j=0;j<=k;j++)
            for (int t=0;t<3;t++)
                dp[i][j][t]=-INF;
        dp[i][0][0]=dp[i][1][2]=0;
    }
    dfs(1,0);
    ans=max(dp[1][k][0],max(dp[1][k-1][1],dp[1][k][2]));
    printf("%lld\n",ans);
    return 0;
}

标签:八省,int,Luogu4383,tot,联考,cost,kz,ckmx,dp
来源: https://www.cnblogs.com/GK0328/p/13525084.html