bzoj1812: [Ioi2005]riv

太假了居然过了样例就A了

这个做法应该是一个O(n^4)的,相信大家都看出来了

这是一个树背包的问题,相信大家也都看出来了

然而怎么背包是个问题QWQ,因为选择了一个点建伐木场,就会影响父亲节点的决策

我只会O(n^2kmaxW)(相当于O(n^5))假设到了当前点有多少木头没有被运到伐木场......

%了一发,发现一个很流弊的操作

f[i][j][u]表示以i为根的子树,修了j个伐木场,最远的伐木场在u的最小花费

规定了最远的u,那就可以直接算当前子树的贡献了

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

struct node
{
    int x,y,next;
}a[110];int len,last[110];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}
int n,m,w[110],fa[110],dep[110],tot[110];
int f[110][110][110];//以i为根的子树,修了j个伐木场,最远的伐木场在u的最小花费 
int tim[110],ti[110][110][110];
void treeDP(int x)
{
    f[x][1][x]=0;
    if(x==0)f[x][0][x]=0;
    for(int u=fa[x];u!=-1;u=fa[u])
        f[x][0][u]=(dep[x]-dep[u])*w[x];
    tot[x]=1;
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;dep[y]+=dep[x];
        treeDP(y);
        tim[x]++;
        for(int i=min(tot[x],m);i>=0;i--)
            for(int j=min(tot[y],m);j>=0;j--)
            {
                if(i+j>m)continue;
                for(int u=x;u!=-1;u=fa[u])
                    if(f[x][i][u]!=f[n+1][m+1][n+1])
                    {
                        if(ti[x][i+j][u]!=tim[x])
                        {
                            ti[x][i+j][u]=tim[x];
                            f[x][i+j][u]=f[x][i][u]+min(f[y][j][u],f[y][j][y]);
                        }
                        else f[x][i+j][u]=min(f[x][i+j][u],f[x][i][u]+min(f[y][j][u],f[y][j][y]));
                    }
            }
        tot[x]+=tot[y];
    }
}
int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    scanf("%d%d",&n,&m);
    len=0;memset(last,0,sizeof(last));
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d%d",&w[i],&fa[i],&dep[i]);
        ins(fa[i],i);
    }
    memset(f,63,sizeof(f));
    memset(tim,0,sizeof(tim));
    memset(ti,0,sizeof(ti));
    fa[0]=-1;dep[0]=0;treeDP(0);
    printf("%d\n",f[0][m][0]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/AKCqhzdy/p/9845448.html