Для данного DAG (направленного ациклического графа) каждый из его топологических сортов является перестановкой всех вершин, где для каждого ребра (u, v) в DAG, u появляется перед v в перестановке.
Ваша задача - вычислить общее количество топологических видов данного DAG.
правила
- Вы можете использовать любой формат для представления графа, например матрицу смежности, список смежности или список ребер, если вы не выполняете полезные вычисления в своей кодировке. Вы также можете иметь такие вещи, как количество вершин или список вершин на входе, если они полезны.
- Вы можете предположить, что график на входе всегда DAG (не имеет циклов).
- Ваша программа должна работать теоретически для любого входа. Но он может потерпеть неудачу, если переполнит базовый целочисленный тип в вашем языке.
- Имена вершин могут быть любыми последовательными значениями в любом типе. Например: числа, начинающиеся с 0 или 1. (И, конечно, только если вы не храните код в этом номере.)
- Это код-гольф. Самый короткий код выигрывает.
пример
Это один и тот же вход в разных форматах. Ваша программа не должна принимать все из них. Вершины всегда целые, начиная с 0.
Adjacency list:
[ [1 2 3 5] [2 4] [] [2] [] [3] ]
Adjacency matrix:
[ [0 1 1 1 0 1] [0 0 1 0 1 0] [0 0 0 0 0 0] [0 0 1 0 0 0] [0 0 0 0 0 0] [0 0 0 1 0 0] ]
Edge list:
6 [ [0 1] [0 2] [0 3] [0 5] [1 2] [1 4] [3 2] [5 3] ]
Это график, показанный на этом изображении:
Выход должен быть:
9
Топологическими видами являются:
[0 1 4 5 3 2]
[0 1 5 4 3 2]
[0 1 5 3 4 2]
[0 1 5 3 2 4]
[0 5 1 4 3 2]
[0 5 1 3 4 2]
[0 5 1 3 2 4]
[0 5 3 1 4 2]
[0 5 3 1 2 4]
code-golf
combinatorics
graph-theory
permutations
jimmy23013
источник
источник
Ответы:
CJam - 25
С большой помощью user23013 :)
Попробуйте онлайн
Объяснение:
Общий алгоритм такой же, как и в решении xnor Python .
Ключевым моментом здесь является
j
оператор, который делает запомненную рекурсию. Он принимает параметр, значение или массив для начальных значений (как в f (0), f (1) и т. Д.) И блок для определения рекурсии.j
Оператор снова используется внутри блока для ведения рекурсивных (и memoized) вызовы в одном блоке. Его также можно использовать с несколькими параметрами, но здесь это не так.Отличным нововведением user23013 является использование j с различными типами данных, используя список смежности в качестве массива начальных значений.
источник
Python, 58
Входные данные состоят из словаря смежности
G
и набора вершинV
.Код рекурсивный. Набор
V
хранит все узлы, которые все еще нуждаются в посещении. Для каждого потенциального следующего узла мы проверяем его пригодность, проверяя, указывают ли на него оставшиеся вершины,V-G[v]==V
проверяя егоV
иG[v]
не пересекаясь. Для всех подходящих таких вершин мы добавляем количество топологических сортировок с удаленными ими. В качестве базового случая пустой набор дает 1.источник
Mathematica,
805751 байтОчень прямолинейная реализация определения. Я просто генерирую все перестановки и подсчитываю, сколько из них допустимо. Чтобы проверить правильность перестановки, я получаю все пары вершин в перестановке. Удобно, что
Subsets[l,{2}]
не только дает мне все пары, но и поддерживает порядок, в котором они находятсяl
- только то, что мне нужно.Выше приведена функция, которая ожидает список вершин и список ребер, как
если вы вызываете функцию
f
.Я попробую сыграть в гольф, или, возможно, воспользуюсь другим подходом позже.
источник
Pyth, 27 байт
Определяет функцию 2 входа
g
. Первый вход - количество вершин, второй - список направленных ребер.Тестировать:
Попробуй это здесь.
источник
^UGG
, который генерирует всеG
списки записейrange(len(G))
.[0, 1, ...]
непосредственно на входе?^GlG
против^UGG
.Haskell,
1021071008985 байтВ качестве входных данных используется наибольшее число вершин (начиная с 0) и список ребер, где ребро представляет собой список из двух элементов. Пример использования:
5 # [[0,1], [0,2], [0,3], [0,5], [1,2], [1,4], [3,2], [5,3]]
Как это работает: подсчитайте все перестановки
p
вершин, которым[u,v]
удовлетворяют все ребра : положениеu
inp
меньше, чем положениеv
inp
. Это прямая реализация определения.Изменить: моя первая версия вернула топологические сортировки сами, а не сколько их есть. Починил это.
Редактировать II: не работал для графов с несвязанными вершинами. Починил это.
источник