D. Arpa's weak amphitheater and Mehrdad's valuable Hoses 分组背包模板题

http://codeforces.com/problemset/problem/742/D

并查集预处理出所有关系。

一开始的时候,我预处理所有关系后,然后选择全部的时候,另起了一个for,然后再判断。

这样是不对的。因为这样使得同一组里面可能选择了两次。

3 0 2

1 2 3

1 1 3

 

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;


#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const int maxn = 2e3 + 20;
int w[maxn];
int bea[maxn];
int fa[maxn];
int tofind(int x) {
    if (fa[x] == x) return x;
    else return fa[x] = tofind(fa[x]);
}
void tomerge(int x, int y) {
    x = tofind(x);
    y = tofind(y);
    fa[y] = x;
}
vector<int>a[maxn];
int dp[1000 + 20];
void work() {
    int n, m, tot;
    cin >> n >> m >> tot;
    for (int i = 1; i <= n; ++i) fa[i] = i;
    for (int i = 1; i <= n; ++i) cin >> w[i];
    for (int i = 1; i <= n; ++i) cin >> bea[i];
    for (int i = 1; i <= m; ++i) {
        int u, v;
        cin >> u >> v;
        tomerge(u, v);
    }
    for (int i = 1; i <= n; ++i) {
        a[tofind(i)].push_back(i);
    }
    int tn = n;
    for (int i = 1; i <= n; ++i) {
        if (a[i].size() == 0) continue;
        int ww = 0, bb = 0;
        for (int k = 0; k < a[i].size(); ++k) {
            ww += w[a[i][k]];
            bb += bea[a[i][k]];
        }
        w[++tn] = ww;
        bea[tn] = bb;
        a[i].push_back(tn);
    }
    for (int i = 1; i <= n; ++i) {
        if (a[i].size() == 0) continue;
        for (int j = tot; j >= 0; --j) {
            for (int k = 0; k < a[i].size(); ++k) {
                if (j >= w[a[i][k]]) {
                    dp[j] = max(dp[j], dp[j - w[a[i][k]]] + bea[a[i][k]]);
                }
            }
        }
//        int ww = 0, bbea = 0;
//        for (int k = 0; k < a[i].size(); ++k) {
//            ww += w[a[i][k]];
//            bbea += bea[a[i][k]];
//        }
//        for (int j = tot; j >= ww; --j) {
//            dp[j] = max(dp[j], dp[j - ww] + bbea);
//        }
    }
    cout << dp[tot] << endl;
}

int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
    work();
    return 0;
}
View Code

 

posted on 2017-01-20 20:18  stupid_one  阅读(145)  评论(0编辑  收藏  举报

导航