01背包和并查集结合
int finde(int x) {//查
if (pre[x] == x)return x;
return pre[x] = finde(pre[x]);
}
void join(int x, int y) {//并
int fx = finde(x);int fy = finde(y);
if (fx != fy)pre[fx] = fy;
}
#include
using namespace std;
const int M = 1e4 + 9;
int dp[M], pre[M], v[M], w[M];
int finde(int x) {
if (pre[x] == x)return x;
return pre[x] = finde(pre[x]);
}
void join(int x, int y) {
int fx = finde(x);int fy = finde(y);
if (fx != fy)pre[fx] = fy;
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, m, r;cin >> n >> m >> r;
for (int i = 1;i <= n;i++)cin >> v[i] >> w[i];
for (int i = 1;i < M;i++)pre[i] = i;
int a, b;
for (int i = 1;i <= m;i++) {
cin >> a >> b;
join(a, b);
}
for (int i = 1;i <= n;i++) {
if (pre[i] != i) {
v[finde(i)] += v[i];
v[i] = 0;
w[finde(i)] += w[i];
w[i] = 0;
}
}
for (int i = 1;i <= n;i++) {
for (int j = r;j >= v[i];j--) {
dp[j] = max(dp[j], dp[j - v[i]] + w[i]);
}
}
cout << dp[r];
return 0;
}