グラフの色付けの問題のように聞こえます。ジャックが「黒」グループに属していることを宣言することから始めます。これは、ジムが「赤」グループに属していなければならないことを意味します。これは、'Rose' が 'black group' に属している必要があることを意味します。ここで衝突が発生します。バラは「黒」なので、ジャックは「赤」である必要がありますが、すでに黒を割り当てています。
編集:実装用の疑似コード(コンパイルしていませんが、メモリリークが発生することはわかっています)
enum Group {
UNKNOWN,
RED,
BLACK
};
struct Person
{
string name;
Group group;
set<Person*> exclusionList;
}
class Class
{
public:
void addExclusion(const string& inPersonA, const string& inPersonB)
{
bool first = (mMembers.empty());
Person* personA = findPerson(inPersonA);
Person* personB = findPerson(inPersonB);
personA->exclusinList.insert(personB);
personB->exclusionList.insert(personA);
if (first) {
// special case, assign initial colors
personA->color = BLACK;
personB->color = RED;
} else {
switch (personA->color) {
case UNKNOWN:
switch(personB->color) {
case UNKNOWN:
break; // we can't do anything, nothing is known
case BLACK:
setColor(personA, RED);
break;
case RED:
setColor(personA, BLACK);
break;
}
break;
case RED:
switch (personB->color) {
case UNKNOWN:
setColor(personB, BLACK);
break;
case RED:
throw "EXCLUSION FAILURE";
case BLACK:
break;
}
case BLACK:
switch (personB->color) {
case UNKNOWN:
setColor(personB, BLACK);
break;
case RED:
break;
case BLACK:
throw "EXCLUSION FAILURE";
}
}
}
}
private:
Person* findPerson(const string& inString)
{
Person* rval = mMembers[inString];
if (rval == null) {
rval = new Person(inString, UNKNOWN);
mMembers[inString] = rval;
}
return rval;
}
void setColor(Person* inPerson, Group inColor)
{
if (inPerson->color == inColor)
return; // no op
if (inPerson->color != UNKNOWN && inPerson->color != inColor)
throw "EXCLUSION FAILURE";
// now we know inPerson was UNKNOWN
inPerson->color = inColor;
for (auto iter = inPerson->exclusionList.begin(); iter != inPerson->exclusionList.end(); ++iter) {
setColor(*iter, (inColor == RED) ? BLACK : RED);
}
unordered_map<string, Person*> mMembers;
};