这听起来像是一个图形着色问题。首先声明杰克属于“黑色”组。这意味着吉姆必须在“红色”组中。这意味着“玫瑰”必须在“黑色组”中。现在我们得到了碰撞:因为玫瑰是“黑色”,所以杰克必须是“红色”,但我们已经为他分配了黑色。
编辑:用于实现的伪代码(我还没有编译它,我知道它会泄漏内存)
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;
};