Блог пользователя AGrigorii

Автор AGrigorii, история, 8 лет назад, По-русски

Всем привет! Столкнулся с такой проблемой: а как сжать граф c n ≤ 104, m ≤ 105 (n вершин, m ребер). Т.е. ищем цикл, сжимаем его в одну вершину, и ребра, которые шли в какую-то вершину цикла, перекидываем в нее. Подскажите, пожалуйста, как это сделать оптимально? Как хранить граф, как сливать цикл? Спасибо!

  • Проголосовать: нравится
  • +8
  • Проголосовать: не нравится

»
8 лет назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится

Первое что пришло на ум: запустим дфс из произвольной вершины, для каждого ребра сохраним в каком направлении оно было первый раз рассмотрено этим дфсом (v → u или u → v) и построим ориентированный граф. Дальше найдём в нём компоненты сильной связности и сожмём их в одну вершину.

»
8 лет назад, # |
  Проголосовать: нравится +12 Проголосовать: не нравится

Граф ориентированный или нет? В любом случае за линейное время это делается выделением компонент сильной связности (для орграфов) и компонент реберной двусвязности (для неор графов, это почти тоже самое, что и мосты выделить) известными алгоритмами. Компоненты надо занумеровать, а затем пройтись по всем ребрам и добавить их в граф-результат, соединив вершины соответствующие номерам соединяемых компонент в оригинальном графе.

»
8 лет назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится

Недавно на CodeChef была задача на что-то похожее. Может будет полезно.

»
5 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Думаю это можно сделать с помощью СНМ ищем мосты и проверяем все ребра если это не мост то отправляем его в СНМ потом опять проверяя все ребра берем их лидеров и в новом сжатом графе создаем ребро между лидерами так можно быстро получить новый сжатый граф Извиняюсь за неграмотность