Журнал сравнений
Программа сортировала n различных чисел и записывала в журнал каждое сравнение, которое делала: «число a меньше числа b». Числа пронумерованы от 1 до n, сами значения потерялись, и часть записей журнала тоже. Восстанавливается ли по оставшимся записям порядок всех n чисел?
Если да, выведите YES и номера чисел по возрастанию. Если нет — NO и номера двух чисел, порядок которых по журналу установить нельзя: из записей не следует, что одно меньше другого, даже через цепочку «a < c, c < b». Подходящих пар может быть несколько — годится любая.
Журналы в тестах настоящие: так сравнивали сортировка слиянием, sorted из Python, пирамидальная и быстрая сортировки, когда упорядочивали население и широты городов мира (GeoNames). В некоторых тестах часть записей стёрта.
В первом примере 3 < 1, 1 < 4 и 4 < 2: порядок 3, 1, 4, 2 записан целиком. Во втором известно, что 3 меньше и 1, и 4, а оба они меньше 2, но кто из 1 и 4 меньше — не записано.
Вход
В первой строке n и m (1 ≤ n ≤ 100 000, 0 ≤ m ≤ 200 000). Дальше m строк по два номера a и b (a ≠ b): число a меньше числа b. Записи не противоречат друг другу; одна и та же запись может встречаться несколько раз.
Выход
В первой строке YES или NO. Во второй — для YES все n номеров по возрастанию чисел, для NO — два номера, порядок которых неизвестен.
Примеры
Пример 1
4 4 3 1 1 4 4 2 3 4
YES 3 1 4 2
Пример 2
4 4 3 1 3 4 1 2 4 2
NO 1 4
Ограничения
- Время · Python
- 4000 мс
- Время · Go
- 1500 мс
- Память
- 256 МБ
- Проверка
- 14 тестов
Разбор
Открывайте по ступеням: каждая следующая подсказывает больше. Можно сразу к решению — но задача, решённая с одной подсказкой, запоминается лучше.
1Подсказка 1
Представьте записи как стрелки «меньше → больше». Какое число может оказаться самым маленьким? А если таких кандидатов два?
2Подсказка 2
Самым маленьким может быть только число, в которое не входит ни одна стрелка. Уберите его и повторите. Что значит, если в какой-то момент таких чисел два?
3Идея
Это топологическая сортировка алгоритмом Кана: держим числа, у которых не осталось неучтённых «меньших», и снимаем их по одному. Если готовых чисел в какой-то момент два, их порядок неизвестен. Пусть это u и v и из записей следует u < v — цепочка u < … < w < v. Все её звенья после u ещё не сняты, ведь u сам не снят; значит, у v осталась неучтённая стрелка от w, и v не мог быть готов. Если же готовое число всегда одно, порядок единственный: каждое следующее число обязано идти сразу за предыдущим.
4Разбор
Для каждого числа храним список «больших» и счётчик «меньших». Кладём в очередь всех с нулевым счётчиком; пока очередь не пуста, если в ней больше одного числа — выводим NO и первые два, иначе снимаем число, дописываем его в ответ и уменьшаем счётчики у его «больших». Повторы записей не мешают: каждая запись увеличила счётчик и ровно один раз его уменьшит.
Что это значит для сортировок. Порядок восстанавливается тогда и только тогда, когда для каждой пары соседей в итоговом порядке есть прямая запись. Поэтому любая правильная сортировка сравнениями обязана сравнить каждую пару соседей, — так в статье доказаны нижние границы для слияния и для проверки, что все числа разные. Стирать из журнала записи о не-соседях можно сколько угодно; потеря одной записи о соседях делает порядок неизвестным. В седьмом тесте из журнала сортировки слиянием стёрта сотня записей, и порядок восстанавливается; в шестом — одна, и уже нет.
4+Решение
5Сложность
O(n + m) времени и памяти.
6Типичные ошибки
- Смотреть только на края. Если самое маленькое и самое большое число однозначны, середина всё равно может быть неизвестна — как во втором примере. Это
wrong.py. - Считать записи. «Записей не меньше n − 1, значит, порядок известен» — неверно: важно, о каких парах записи, а не сколько их.
- Строить транзитивное замыкание. Проверка всех пар на достижимость — это O(n·m), на ста тысячах чисел слишком долго.
Алгоритмы задачи
сортировка — ⌈log₂ n!⌉ сравнений
1 задача
GRA
Алгоритм
Топологическая сортировка
Выстраивает вершины графа без циклов так, чтобы все рёбра смотрели вперёд, за O(V + E).
O(V + E)
2 задачи