zoukankan      html  css  js  c++  java
  • [LUOGU] P3354 [IOI2005]Riv 河流

    题目描述
    几乎整个Byteland王国都被森林和河流所覆盖。小点的河汇聚到一起,形成了稍大点的河。就这样,所有的河水都汇聚并流进了一条大河,最后这条大河流进了大海。这条大河的入海口处有一个村庄——名叫Bytetown。
    
    在Byteland国,有n个伐木的村庄,这些村庄都座落在河边。目前在Bytetown,有一个巨大的伐木场,它处理着全国砍下的所有木料。木料被砍下后,顺着河流而被运到Bytetown的伐木场。Byteland的国王决定,为了减少运输木料的费用,再额外地建造k个伐木场。这k个伐木场将被建在其他村庄里。这些伐木场建造后,木料就不用都被送到Bytetown了,它们可以在运输过程中第一个碰到的新伐木场被处理。显然,如果伐木场座落的那个村子就不用再付运送木料的费用了。它们可以直接被本村的伐木场处理。
    
    注:所有的河流都不会分叉,形成一棵树,根结点是Bytetown。
    
    国王的大臣计算出了每个村子每年要产多少木料,你的任务是决定在哪些村子建设伐木场能获得最小的运费。其中运费的计算方法为:每一吨木料每千米1分钱。
    
    输入输出格式
    输入格式:
    第一行包括两个数 n(2≤n≤100),k(1≤k≤50,且 k≤n)。n为村庄数,k为要建的伐木场的数目。除了Bytetown外,每个村子依次被命名为123……n,Bytetown被命名为0。
    
    接下来n行,每行3个整数:
    
    wi——每年i村子产的木料的块数(0≤wi≤10000)
    
    vi——离i村子下游最近的村子(即i村子的父结点)(0≤vi≤n)
    
    di——vi到i的距离(千米)。(1≤di≤10000)
    
    保证每年所有的木料流到bytetown的运费不超过2,000,000,00050%的数据中n不超过20。
    
    输出格式:
    输出最小花费,单位为分。
    
    输入输出样例
    输入样例#1: 
    4 2
    1 0 1
    1 1 10
    10 2 5
    1 2 3
    输出样例#1: 
    4

    树上分组背包+约定祖先

    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    inline int rd() {
        int ret=0,f=1;
        char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    const int MAXN=155;
    
    struct Edge {
        int next,to,w;
    } e[MAXN];
    int ecnt,head[MAXN];
    inline void add(int x,int y,int w) {
        e[++ecnt].next = head[x];
        e[ecnt].to = y;
        e[ecnt].w = w;
        head[x] = ecnt;
    }
    
    int n,k;
    int val[MAXN];
    int f[MAXN][MAXN][MAXN];
    int g[MAXN][MAXN][MAXN];
    int stack[MAXN],top;
    int dep[MAXN];
    
    void dfs(int x) {
        stack[++top]=x;
        for(int i=head[x]; i; i=e[i].next) {
            int v=e[i].to;
            dep[v]=dep[x]+e[i].w;
            dfs(v);
            for(int fa=1; fa<=top; fa++) {
                for(int j=k; j>=0; j--) {
                    f[x][j][stack[fa]]+=f[v][0][stack[fa]];
                    g[x][j][stack[fa]]+=f[v][0][x];
                    for(int u=0; u<=j; u++) {//
                        f[x][j][stack[fa]]=min(f[x][j][stack[fa]],f[x][j-u][stack[fa]]+f[v][u][stack[fa]]);
                        g[x][j][stack[fa]]=min(g[x][j][stack[fa]],g[x][j-u][stack[fa]]+f[v][u][x]);
                    }
                }
            }
        }
        for(int fa=1; fa<=top; fa++) {
            for(int j=0; j<=k; j++) {
                if(j>=1) f[x][j][stack[fa]]=min(f[x][j][stack[fa]]+val[x]*(dep[x]-dep[stack[fa]]),g[x][j-1][stack[fa]]);
                else f[x][j][stack[fa]]+=val[x]*(dep[x]-dep[stack[fa]]);
            }
        }
    
    
        top--;
    }
    
    int main() {
        n=rd();
        k=rd();
        for(int i=1; i<=n; i++) {
            int y,w;
            val[i]=rd();
            y=rd();
            w=rd();
            add(y,i,w);
        }
        dfs(0);
        cout<<f[0][k][0];
        return 0;
    }

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9247404.html

  • 相关阅读:
    智能推荐算法演变及学习笔记(三):CTR预估模型综述
    从中国农业银行“雅典娜杯”数据挖掘大赛看金融行业数据分析与建模方法
    智能推荐算法演变及学习笔记(二):基于图模型的智能推荐(含知识图谱/图神经网络)
    (设计模式专题3)模板方法模式
    (设计模式专题2)策略模式
    (设计模式专题1)为什么要使用设计模式?
    关于macOS上常用操作命令(持续更新)
    记录下关于RabbitMQ常用知识点(持续更新)
    EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
    SpringCloud教程二:Ribbon(Finchley版)
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9247404.html
Copyright © 2011-2022 走看看