#include <iostream>
#include <vector>
#include <unordered_set>
#include <algorithm>
using namespace std;
class SetCover {
private:
unordered_set<int> universe; // 存储要覆盖的所有元素
vector<unordered_set<int>> subsets; // 存储所有的子集
public:
// 构造函数,初始化 universe 和 subsets
SetCover(const unordered_set<int>& u, const vector<unordered_set<int>>& sets)
: universe(u), subsets(sets) {}
// 贪心算法实现,返回选择的子集索引
vector<int> greedyCover() {
vector<int> cover; // 存储选择的子集索引
unordered_set<int> covered; // 存储已经覆盖的元素
// 循环直到所有元素都被覆盖
while (covered.size() < universe.size()) {
int best_subset = -1; // 当前最好的子集索引
unordered_set<int> best_elements; // 当前子集能覆盖的元素
// 遍历所有子集
for (int i = 0; i < subsets.size(); i++) {
// 如果子集已经被选择,跳过
if (find(cover.begin(), cover.end(), i) != cover.end()) {
continue;
}
unordered_set<int> new_elements; // 当前子集能覆盖的新元素
// 遍历子集中的每个元素
for (int elem : subsets[i]) {
// 如果元素未被覆盖,加入 new_elements
if (covered.find(elem) == covered.end()) {
new_elements.insert(elem);
}
}
// 如果 new_elements 比 best_elements 覆盖更多新元素,更新 best_subset 和 best_elements
if (new_elements.size() > best_elements.size()) {
best_subset = i;
best_elements = new_elements;
}
}
// 如果无法找到新的子集来覆盖剩余元素,跳出循环
if (best_subset == -1) {
break;
}
// 将最好的子集索引加入 cover
cover.push_back(best_subset);
// 将新的元素加入 covered
covered.insert(best_elements.begin(), best_elements.end());
}
return cover;
}
// 打印选择的子集
void printCover(const vector<int>& cover) {
cout << "Selected subsets:" << endl;
// 遍历 cover,输出每个子集的索引和包含的元素
for (int i : cover) {
cout << "Subset " << i << ": ";
for (int elem : subsets[i]) {
cout << elem << " ";
}
cout << endl;
}
}
};
int main() {
unordered_set<int> universe = {1, 2, 3, 4, 5}; // 要覆盖的所有元素
vector<unordered_set<int>> subsets = { // 子集的集合
{1, 2, 3},
{2, 4},
{3, 4},
{4, 5}
};
SetCover sc(universe, subsets); // 创建 SetCover 对象
vector<int> cover = sc.greedyCover(); // 调用 greedyCover 获取覆盖子集的索引
sc.printCover(cover); // 调用 printCover 打印选择的子集
return 0;
}