#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <vector>
#include <set>
using SourceType = std::vector<std::pair<std::size_t, std::set<int>>>;
using ResultType = std::vector<std::pair<std::vector<std::size_t>, std::set<int>>>;
int main() {
// исходные данные
SourceType S = {
{ 1, { 1, 3, 4 }},
{ 2, { 5, 6, 8 }},
{ 3, { 1, 4, 5 }},
{ 4, {11, 12, 14 }},
{ 5, {10, 18, 12 }}
};
// получаемые данные
ResultType R;
// текущий индекс обработчика
std::size_t Jump = (S.size()) ? 2 : 0;
// текущий индекс обрабатываемого элемента
std::size_t IdxS = 0;
// текущий индекс элемента группы
std::size_t IdxR = 0;
// поехали
while (Jump) {
switch (Jump) {
case 1: // проверка на необходимость дальнейшей обработки
Jump = (S.size()) ? 4 : 0;
break;
case 2: // создание группы
R.push_back({{}, {}});
IdxR = R.size() - 1;
case 3: // занесение в группу текущего элемента
R[IdxR].first.push_back(S[IdxS].first);
R[IdxR].second.merge(S[IdxS].second);
S.erase(S.begin() + IdxS);
IdxS = 0;
IdxR = 0;
Jump = 1;
break;
case 4: // проверка необходимости занесения текущего элемента в текущую группу
std::set<int> intersection;
std::set_intersection(S[IdxS].second.begin(), S[IdxS].second.end(), R[IdxR].second.begin(), R[IdxR].second.end(), std::inserter(intersection, intersection.begin()));
if (intersection.empty()) {
if (IdxR + 1 < R.size())
IdxR++;
else {
if (IdxS + 1 < S.size()) {
IdxS++;
IdxR = 0;
Jump = 1;
} else
Jump = 2;
}
} else
Jump = 3;
}
}
// Печать результата
char Curr = 'A';
std::cout << std::endl;
for (auto& i : R) {
std::ostringstream ossg;
std::sort(i.first.begin(), i.first.end());
std::copy(i.first.begin(), i.first.end(), std::ostream_iterator<int>(ossg, " "));
std::cout << "Group [" << Curr++ << "]: " << ossg.str() << std::endl;
std::ostringstream ossb;
std::copy(i.second.begin(), i.second.end(), std::ostream_iterator<int>(ossb, " "));
std::cout << " bitset: " << ossb.str() << std::endl;
}
std::cout << std::endl;
return 0;
}