zoukankan      html  css  js  c++  java
  • bzoj1812 riv(树形背包)

    dp[i][j][k]表枚举到第i个节点,以该结点为根的子树中建了k个伐木场,距离i最近的伐木场是j的最小距离

    有一些细节。。。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int n,m,cnt;
    int head[205];
    int fa[205];
    int val[205];
    int dis[205][205];
    int dp[205][205][55];
    struct Edge{
        int to;
        int nxt;
    }edge[205];
    void init(){
        memset(head,-1,sizeof(head));
        memset(fa,-1,sizeof(fa));
    }
    void addedge(int f,int t){
        cnt++;
        edge[cnt].to=t;
        edge[cnt].nxt=head[f];
        head[f]=cnt;
    }
    void DFS(int p){
        int la=p;
        for(int i=fa[p];i!=-1;i=fa[i]){
            dis[p][i]=dis[p][la]+dis[la][i];
            la=i;
        }
        if(head[p]==-1){
            for(int i=fa[p];i!=-1;i=fa[i]){
                dp[p][i][0]=dis[p][i]*val[p];
            }
            return;
        }
        if(p)dp[p][p][0]=0x3f3f3f3f;
        for(int i=head[p];i!=-1;i=edge[i].nxt){
            int e=edge[i].to;
            DFS(e);
            for(int f=fa[p];f!=-1;f=fa[f]){
                for(int j=m;j>=0;j--){
                    int tmp=0x3f3f3f3f;
                    for(int k=0;k<=j;k++){
                        tmp=min(tmp,dp[p][f][k]+dp[e][f][j-k]);
                    }
                    dp[p][f][j]=tmp;
                }
            }
            for(int j=m;j>=0;j--){
                int tmp=0x3f3f3f3f;
                for(int k=(p!=0);k<=j;k++){
                    tmp=min(tmp,dp[p][p][k]+dp[e][p][j-k]);
                }
                dp[p][p][j]=tmp;
            }
        }
        for(int i=fa[p];i!=-1;i=fa[i]){
            for(int j=0;j<=m;j++){
                dp[p][i][j]+=dis[p][i]*val[p];
                dp[p][i][j]=min(dp[p][i][j],dp[p][p][j]);
            }
        }
    }
    int main(){
        freopen("girls.in","r",stdin);
        freopen("girls.out","w",stdout);
        init();
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            int w;
            scanf("%d%d%d",&val[i],&fa[i],&w);
            addedge(fa[i],i);
            dis[i][fa[i]]=w;
        }
        DFS(0);
        printf("%d
    ",dp[0][0][m]);
        return 0;
    }
  • 相关阅读:
    js 提示框的实现---组件开发之(一)
    js 原型链
    js 哈希路由原理实现
    js 弹窗的实现
    js 滑动门的实现
    Delphi IDFtp用法,包含断点续传
    memortstream Base64编码和filestream base64编码不同
    Delphi另一个多线程函数:BeginThread用法
    delphi 讲的比较详细的多线程(推荐)
    多线程简单实用
  • 原文地址:https://www.cnblogs.com/lnxcj/p/9742837.html
Copyright © 2011-2022 走看看