洛谷p1455 搭配购买

01背包和并查集结合

并查集板子

int finde(int x) {//查
    if (pre[x] == x)return x;
    return pre[x] = finde(pre[x]);
}

void join(int x, int y) {//并
    int fx = finde(x);int fy = finde(y);
    if (fx != fy)pre[fx] = fy;
}

ACcode

#include

using namespace std;

const int M = 1e4 + 9;
int dp[M], pre[M], v[M], w[M];

int finde(int x) {
    if (pre[x] == x)return x;
    return pre[x] = finde(pre[x]);
}

void join(int x, int y) {
    int fx = finde(x);int fy = finde(y);
    if (fx != fy)pre[fx] = fy;
}

int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n, m, r;cin >> n >> m >> r;
    for (int i = 1;i <= n;i++)cin >> v[i] >> w[i];
    for (int i = 1;i < M;i++)pre[i] = i;
    int a, b;
    for (int i = 1;i <= m;i++) {
        cin >> a >> b;
        join(a, b);
    }
    for (int i = 1;i <= n;i++) {
        if (pre[i] != i) {
            v[finde(i)] += v[i];
            v[i] = 0;
            w[finde(i)] += w[i];
            w[i] = 0;
        }
    }
    for (int i = 1;i <= n;i++) {
        for (int j = r;j >= v[i];j--) {
            dp[j] = max(dp[j], dp[j - v[i]] + w[i]);
        }
    }
    cout << dp[r];
    return 0;
}

你可能感兴趣的:(背包专题训练,01背包,并查集,背包dp)