思路
是一个分组背包问题,中间用并查集来进行分组即可
代码
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
const int N=1005;
const int INF=0x3f3f3f;
int p[N*N];
ll v[N];
ll w[N];
ll f[N];
vector<ll> t[N];
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main(){
int n,m,s;
cin >> n >> m >> s;
for(int i=1;i<=n;i++){
cin >> v[i];
p[i]=i;
}
for(int i=1;i<=n;i++){
cin >> w[i];
}
for(int i=1;i<=m;i++){
int x,y;
cin >> x >> y;
p[find(x)] = find(y);
}
for(int i=1;i<=n;i++){
int a=find(i);
t[a].push_back(i);
}
for(int i=1;i<=n;i++){
if(p[i]==i){
for(int j=s;j>=0;j--){
ll sumv=0;
ll sumw=0;
for(int k=0;k<t[i].size();k++){
if(j>=v[t[i][k]])f[j]=max(f[j],f[j-v[t[i][k]]]+w[t[i][k]]);
sumv+=v[t[i][k]];
sumw+=w[t[i][k]];
}
if(j>=sumv)f[j]=max(f[j],f[j-sumv]+sumw);
}
}
}
ll ans=0;
for(int i=0;i<=s;i++)ans=max(ans,f[i]);
cout << ans;
}