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; }