• 【01背包 合并费用】搭配购买


    传送门

    题意

    给定(n)朵云,编号(1,2dots ,n),每个云朵有一个价格(c_{i}),价值(d_{i})
    一共有(w)的钱,一共(m)对关系((u_{i},v_{i}))表示((u_{i},v_{i}))需要一起购买,求最大价值

    数据范围

    (egin{array}{l}1 leq n leq 10000 \ 0 leq m leq 5000 \ 1 leq w leq 10000 \ 1 leq c_{i} leq 5000 \ 1 leq d_{i} leq 100 \ 1 leq u_{i}, v_{i} leq nend{array})

    题解

    将所有需要合并的价值和价格都合并到一个集合中,最后对所有不同集合做(01)背包即可

    Code

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=1e4+10;
    
    int n,m,w;
    int fa[N],c[N],d[N],dp[N];
    
    int find(int x){
        if(fa[x]!=x) fa[x]=find(fa[x]);
        return fa[x];
    }
    void merge(int a,int b){
        int pa=find(a),pb=find(b);
        if(pa!=pb) {
            c[pb] += c[pa];
            d[pb] += d[pa];
            fa[pa] = pb;
        }
    }
    int main(){
        scanf("%d%d%d",&n,&m,&w);
        for(int i=1;i<=n;i++) fa[i] = i;
        for(int i=1;i<=n;i++) scanf("%d%d",&c[i],&d[i]);
        while(m--){
            int u,v; scanf("%d%d",&u,&v);
            merge(u,v);
        }
        for(int i=1;i<=n;i++){
            if(fa[i] == i)
                for(int j=w;j>=c[i];j--){
                    dp[j]=max(dp[j],dp[j-c[i]]+d[i]);
                }
        }
        printf("%d
    ",dp[w]);
    }
    
  • 相关阅读:
    HNOI2018退役记
    codeforces 960G Bandit Blues
    codeforces 933D A Creative Cutout
    tyvj1953 Normal
    loj6119 「2017 山东二轮集训 Day7」国王
    codeforces 293E Close Vertices
    bzoj1808 [Ioi2007]training 训练路径
    bzoj2219 数论之神
    bzoj4361 isn
    loj2064[HAOI2016]找相同字符
  • 原文地址:https://www.cnblogs.com/hhyx/p/13426523.html
Copyright © 2020-2023  润新知