本题大意:绑定销售求最大价值
对于绑定的价值可以采用并查集进行维护每一个’大物品’的v和w,完成操作后做一次01背包问题即可
import java.util.*;
public class Main {
static final int N = 10010;
static int[] f = new int[N], p = new int[N];
static int[] v = new int[N], w = new int[N];
static int n, m, vol;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
vol = sc.nextInt();
for (int i = 1; i <= n; i++) p[i] = i;
for (int i = 1; i <= n; i++) {
v[i] = sc.nextInt();
w[i] = sc.nextInt();
}
//并查集操作
for (int i = 0; i < m; i++) {
int a = sc.nextInt(), b = sc.nextInt();
int pa = find(a), pb = find(b);
if (pa != pb) {//不能在同一个集合中
v[pb] += v[pa];数值存储在根节点中
w[pb] += w[pa];
p[pa] = pb;//将pa连接到pb上
}
}
//01背包
for (int i = 1; i <= n; i++)
if (i == p[i])//需要时根节点的物品才有意义
for (int j = vol; j >= v[i]; j--)
f[j] = Math.max(f[j], f[j - v[i]] + w[i]);
System.out.println(f[vol]);
}
static int find(int u) {
if (u != p[u]) p[u] = find(p[u]);
return p[u];
}
}