1. 程式人生 > 實用技巧 >【】搭配購買

【】搭配購買

傳送門

題意

商店有\(n\)朵雲,編號\(1,2\dots ,n\),每個雲朵有一個價值,

資料範圍

\(\begin{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 n\end{array}\)

題解

Code

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define close ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
const int N=1e4+10;
int n,m,w;
int fa[N],weight[N],val[N];
int f[N];

int find(int x){
    if(fa[x]!=x) fa[x]=find(fa[x]);
    return fa[x];
}

void merge(int a,int b){
    int fa_a=find(a),fa_b=find(b);

    if(fa_a!=fa_b) {
        weight[fa_b] += weight[fa_a];
        val[fa_b] += val[fa_a];
        fa[fa_a] = fa_b;
    }
}

int main(){
    scanf("%d%d%d",&n,&m,&w);
    rep(i,1,n+1) fa[i] = i;
    rep(i,1,n+1) scanf("%d%d",&weight[i],&val[i]);

    while(m--){
        int u,v;
        scanf("%d%d",&u,&v);

        merge(u,v);
    }

    rep(i,1,n+1){
        if(fa[i] == i)
            per(j,weight[i],w+1){
                f[j]=max(f[j],f[j-weight[i]]+val[i]);
            }
    }

    printf("%d\n",f[w]);
}