Files
python/TangDou/XiTi/1414.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

66 lines
2.2 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
const int N = 10005;
int w[N]; //价钱
int d[N]; //价值(美丽值)
int f[N];
int dp[N];
//并查集
int find(int x) {
if (f[x] == x) return x;
return f[x] = find(f[x]);
}
// 【解题思路】
// 并查集+01背包都是基本算法╮(╯▽╰)╭
// 先读进来那一堆价格和价值,然后读进来他们的关系,把有关系的两个合并在一个集合里。
// 做完并查集了之后把相同代表元素的价格加在一起,价值加在一起,我们就得到了数量<=n的物品可以做一次01背包就能求出题目要求的解
// 题解:利用并查集把必须一起购买的合并到一起,然后 将一个集合中的物品看做一个物品变成经典的01背包问题。
int main() {
//输入+输出重定向
freopen("../1414.txt", "r", stdin);
int n, m, v; //nmv表示n朵云m个搭配Joe有v的钱。
cin >> n >> m >> v;
for (int i = 1; i <= n; i++) {
f[i] = i;//每个人都是自己的爸爸
cin >> w[i] >> d[i]; //每行widi表示i朵云的价钱和价值(美丽值)。
}
//读取它们之间的关系,把有关系的两个合并在一个集合里。
int x, y;
while (m--) {
cin >> x >> y;
int a = find(x), b = find(y);
if (a != b) {
f[b] = a; //a是老大b里面记录它是a的孩子
w[a] += w[b]; //它爸爸管理价格,它自己没有资格参加
d[a] += d[b]; //它爸爸管理价值(美丽值),它自己没有资格参加
}
}
//
// cout << "打印w数组进行调试" << endl;
// for (int i = 1; i <= n; i++) cout << w[i] << " ";
// cout << endl;
// cout << "打印d数组进行调试" << endl;
// for (int i = 1; i <= n; i++) cout << d[i] << " ";
// cout << endl;
//01背包
for (int i = 1; i <= n; i++) {
if (f[i] == i) //如果有权利参加的爸爸们!
for (int j = v; j >= w[i]; j--) {
dp[j] = max(dp[j], dp[j - w[i]] + d[i]);
}
}
cout << dp[v];
//关闭文件
fclose(stdin);
return 0;
}