Давайте выясним для каждого подмножества S запрещенных ребер, сколько существует гамильтоновых циклов, которые используют все ребра S. Если мы решим эту подзадачу, то мы решим задачу по формуле включения-исключения .
Теперь, как мы решаем подзадачу?Давайте нарисуем все ребра S. Если существует вершина степени больше 2, то, очевидно, мы не можем завершить цикл, и ответ равен 0. В противном случае граф делится на связанные компоненты.Каждый компонент является единственной вершиной, циклом или простым путем.
Если существует цикл, то он должен проходить через все вершины, иначе мы не сможем завершить гамильтонов цикл.Если это так, ответ равен 2. (Цикл может быть пройден в 2 направлениях.) В противном случае ответ равен 0.
Остается случай, когда есть c путей и k единственные вершины.Чтобы завершить гамильтонов цикл, мы должны выбрать направление каждого пути ( 2 ^ c путей), а затем выбрать порядок компонентов.У нас есть c + k компонентов, поэтому их можно переставить (c + k)! способами.Но нас интересуют циклы, поэтому мы не различаем упорядочения, которые превращаются друг в друга циклическими сдвигами.(Таким образом, (1,2,3), (2,3,1) и (3,1,2) одинаковы.) Это означает, что мы должны разделить ответ на количество смен, c + k.Таким образом, ответ (на подзадачу): 2 ^ c (c + k-1)! .
Эта идея реализована в решении bmerry (очень чистый код, кстати).