Да, про разделение потока я не сообразил. Вроде получается что exact cover by 3-sets к этому сводится, но аккуратно расписать возможности пока нет.
Идея следующая: для каждого множества
добавляем числа (для каждого множества свои)
и
, которые я буду для удобства обозначать просто латинскими буквами из начала алфавита. Плюс все исходное множество считаем пронумерованным.
Добавляем в
группу 1 - элементы
- их будем брать, если наше множество входит в покрытие. Дополнительно добавляем группу 2 -
- их будем брать, если наше множество не входит в покрытие.
Чтобы все же покрыть 1,2,3, если наше множество входит в покрытие, добавляем ещё элементы
. Ну и чтобы захватить
, если множество не входит в покрытие, заранее добавляем отдельно столько чисел, сколько множество не попадет в покрытие, и соединяем
со всеми возможными парами этих дополнительных чисел.
Если я ничего не путаю, то мы обязаны взять либо все элементы из группы один, либо все элементы из группы два. И по этому однозначно восстанавливается покрытие - в него входят все множества, для которых выбрана группа 1. Наоборот, по любому покрытию определяется, какую группу для каждого множества надо брать (а для
из множеств, не взятых в покрытие, набрать что угодно из дополнительных чисел - например, сделать цикл).