Я не был уверен в добавлении другого ответа, но ответ от user3386109 дал мне понимание того, что я считаю законченным решением, и я чувствовал, что оно слишком сильно отличается от духа моего оригиналаответ для включения в качестве правки.
Напомним, у нас есть несколько инструментов ниже пояса:
Мы можем оптимально обрезать узлы с одним ребром, повторяя процессдо завершения
Мы можем назначить направление любому ребру в простом цикле (соединенные компоненты только с узлами степени 2), а остальное последует (оптимально).
Узлы с двумя ребрами в более сложных циклах можно временно игнорировать, так как их направления ребер будут назначаться узлами более высокой степени.
После прочтения последней точки,сама проблема становится немного яснее.После того, как мы удалили узлы степени один в пуле один, все остальные узлы имеют как минимум два ребра.Мы можем с уверенностью сказать в оптимальном графе, что каждый из этих узлов будет иметь хотя бы одно направленное ребро, указывающее на них.В качестве доказательства, поскольку каждый узел имеет по крайней мере два ребра, но связанный компонент не является простым циклом (иначе это будет исключено в пуле 2), у нас больше ребер, чем узлов.Если какой-либо узел имеет нулевые ребра, направленные к нему, один из этих ребер может быть обращен вспять, чтобы уменьшить количество конфликтующих ребер или «освободить» другой узел, чтобы иметь нулевые внутренние ребра, чтобы затем сделать то же самое.
Вооружившись этим знанием, мы знаем, что минимальное количество конфликтов (дополнительные ребра, направленные на узлы, у которых уже есть ребро, направленное на них), равно количеству ребер минус количество вершин в нашем обрезанном графе.Мы также можем сделать вывод, что до тех пор, пока нам удастся направить по крайней мере одно ребро на каждый узел, у нас будет оптимальный график, независимо от того, как мы рассеиваем конфликтующие ребра.
Изначально я пытался составить алгоритмна основании третьего пункта для выполнения этого задания, но оказывается, что ответ на самом деле намного проще, чем даже.Единственный способ, которым мы можем случайно создать узел без ребер, направленных от него, - это активное направление всех ребер от этого узла.Решение состоит в том, чтобы выбрать одно ребро в подключенном компоненте и назначить ему случайное направление.Затем выполните поиск (DFS, BFS и т. Д.) Вне узла, на который он направлен, назначая направления ребрам по ходу движения в том направлении, в котором вы их проходите.Любой узел, к которому вы достигнете, будет иметь ребро, направленное на него (ребро, которое вы взяли, чтобы добраться до него), а корневой узел будет иметь ребро, которое вы ему присвоили вручную.
В итоге получится график сминимальное количество дополнительных ребер, направленных на узлы.Если вы вместо этого хотите минимизировать количество узлов, содержащих конфликтующие ребра, решите проблему, как указано выше, а затем сформируйте подграф узлов степени три или более и их соединительных ребер.Найдите минимальное покрытие вершин этого подграфа, а затем измените направление ребер, соединяющих узлы, не находящиеся в минимальном покрытии вершин, но содержащие конфликтующие ребра, с соответствующими узлами в минимальном покрытии вершин.