Address of Luo Valley
After reading this question, we can see that the following sentence for a circle of friends, either choose one of them or choose all, it is easy to think of the group backpack, then the next consideration is
How to Transform the Form of Component Backpack
Obviously, we can maintain every circle of friends by using and collecting them. So for each circle of friends, we should set up a vector to maintain the people in the circle of friends. At the same time, we should treat everyone as a person, join the circle of friends, and then make a 01 knapsack in the circle. Note that if a person has no friends, then his circle of friends does not need to add another person, otherwise. That person will appear twice.
And because you want to add everyone to the array, the array needs to be opened a little bit larger than the data.
CodeCodeCode
#include<bits/stdc++.h> #define N 5001 #define ll long long using namespace std; inline void read(ll &s){ s = 0; ll w = 1; char ch = getchar(); while(ch < '0' || ch > '9'){if(ch == '-') w = -1, ch = getchar();} while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();} s *= w; return ; } struct node{ int x, y; }e[N]; ll f[N], fa[N], a[N], b[N]; ll n, m, w, p; vector<ll> group[N]; inline ll get(ll x){ return fa[x] == x ? x : fa[x] = get(fa[x]); } int main() { read(n), read(m), read(w); p = n; for(ll i = 1; i <= n; ++i) fa[i] = i, read(a[i]); for(ll i = 1; i <= n; ++i) read(b[i]); for(ll i = 1; i <= m; ++i){ ll x, y; read(x), read(y); x = get(x), y = get(y); if(x != y) fa[y] = x; } for(ll i = 1; i <= n; ++i) group[get(i)].push_back(i); for(ll i = 1; i <= n; ++i){ if(group[i].size() <= 1) continue; group[i].push_back(++p); for(ll j = 0; j < group[i].size() - 1; ++j) a[p] += a[group[i][j]], b[p] += b[group[i][j]]; } for(ll k = 1; k <= n; ++k){ if(!group[k].size()) continue; for(ll j = w; j >= 0; --j) for(ll i = 0; i < group[k].size(); ++i){ ll x = group[k][i]; if(j >= a[x]) f[j] = max(f[j], f[j - a[x]] + b[x]); } } printf("%d\n", f[w]); return 0; }