题目链接:点击打开链接
思路:
在宿舍打CF不敢使劲敲键盘, 最后没交上D也怨不了别人。 挺水的DP, 就是个背包。
细节参见代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <ctime>
#include <bitset>
#include <cstdlib>
#include <cmath>
#include <set>
#include <list>
#include <deque>
#include <map>
#include <queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
typedef long double ld;
const double eps = 1e-6;
const double PI = acos(-1);
const ll mod = 1e9;
const int INF = 0x3f3f3f3f;
// & 0x7FFFFFFF
const int seed = 131;
const ll INF64 = ll(1e18);
const int maxn = 1000+10;
int n, m,lll[maxn],L, W,p[maxn],numw[maxn],numb[maxn],w[maxn],b[maxn],u[maxn],v[maxn],d[maxn][maxn];
int _find(int x) { return p[x] == x ? x : p[x]=_find(p[x]); }
struct node {
int w,b;
node(int w=0,int b=0):w(w),b(b) {}
}vv[maxn][maxn];
int cur[maxn];
int main() {
scanf("%d%d%d", &n, &m, &W);
for(int i = 1; i <= n; i++) {
scanf("%d", &w[i]);
p[i]= i;
}
for(int i = 1; i <= n; i++) {
scanf("%d", &b[i]);
}
for(int i = 1; i <= m; i++) {
int u, v; scanf("%d%d", &u, &v);
int x=_find(u);
int y=_find(v);
if(x != y) p[x]=y;
}
for(int i = 1; i <= n; i++) {
int id=_find(i);
if(id==i) cur[L++] = i;
vv[id][lll[id]++] = node(w[i],b[i]);
numw[id] += w[i];
numb[id] += b[i];
}
memset(d,0,sizeof(d));
for(int i = 1; i <= L; i++) {
int id = cur[i-1];
for(int j = 0; j <= W; j++) {
d[i][j] = max(d[i][j],d[i-1][j]);
if(j-numw[id] >= 0)d[i][j] = max(d[i][j],d[i-1][j-numw[id]]+numb[id]);
for(int k=0; k < lll[id]; k++) {
if(j-vv[id][k].w >= 0)d[i][j] = max(d[i][j],d[i-1][j-vv[id][k].w]+vv[id][k].b);
}
}
}
int ans = 0,len=L;
for(int i = 0; i <= W; i++) {
ans = max(ans, d[len][i]);
}
printf("%d\n",ans);
return 0;
}