У меня есть набор учеников (именуемые в названии предметы для общности). Среди этих студентов некоторые имеют репутацию буйных. Нам рассказывают о множестве отношений ненависти в форме «я ненавижу j». «я ненавижу j» означает , а не означает «j ненавидит меня». Мы должны расположить студентов в ряды (передний крайний ряд с номером 1) таким образом, чтобы, если «я ненавижу j», то меня помещали в ряд, который на строго меньше, чем на j (другими словами: в некоторой строке перед строкой j), чтобы я ничего не бросал в j (возврат назад запрещен). Каким был бы эффективный алгоритм для нахождения минимального необходимого количества строк (в каждой строке не должно быть одинакового количества студентов)?
Мы сделаем следующие предположения:
1) Если мы смоделируем это как ориентированный граф, в графе нет циклов. Самый простой цикл: если «я ненавижу j» - это правда, «j ненавидит i» - это ложь. Потому что в противном случае я думаю, что заказ станет невозможным.
2) Каждый студент в группе, по крайней мере, ненавидится одним другим студентом ИЛИ, по крайней мере, ненавидит одного другого студента. Конечно, найдутся студенты, которых ненавидят одни и которые, в свою очередь, ненавидят других. Это означает, что нет бездомных студентов, которые не составляют часть графика.
Обновление: Я уже думал о построении ориентированного графа с i -> j, если 'я ненавижу j, и выполнении топологической сортировки. Однако, поскольку общая топологическая сортировка была бы лучше, если бы я выстроил всех студентов в одну строку. Поскольку здесь есть варианты строк, я пытаюсь выяснить, как включить изменение в топологическую сортировку, чтобы оно дало мне то, что я хочу.
Когда вы отвечаете, пожалуйста, укажите сложность вашего решения. Если кто-то даёт код, а вы не против языка, то я бы предпочел Java, но, конечно, любой другой язык так же хорош.
JFYI Это не для каких-либо домашних заданий (кстати, я не студент):