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

Автор Furko, 12 лет назад, По-русски

Недавно встретил данную задачу для ограничений N<=100, M<=10000. Первая мысль была минкост, но он будет очень долго работать, так как сложность минкоста О(N^3*M). Подскажите пожалуйста, как решить заданную задачу за подходящее время (1-3 сек).

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

»
12 лет назад, # |
Rev. 2   Проголосовать: нравится +25 Проголосовать: не нравится
»
12 лет назад, # |
  Проголосовать: нравится +8 Проголосовать: не нравится
  • »
    »
    12 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится +3 Проголосовать: не нравится

    Оно! Но выше написан, как по мне, легче алгоритм.

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

      Это один и тот же алгоритм:)

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

        так там с циклов нужно ребра удалять, а там как то строить конденсацию.

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

          Третий пункт — чем тебе не конденсация? Ну и в начале, как бы, ссылаются на алгоритм Чу и Лю.

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

Если уж зашел разговор на эту тему — Тарьян давным-давно придумал, как это за O(n2) без тяжеловесных структур данных делать. Идея — будем стягивать циклы в вершину не пачками, а по одному, и использовать матрицу смежности.

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

    Можно более подробно?

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

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

      Почему это O(n2)? Всего будет создано O(n) вершин. Каждую вершину мы обработает единожды. Для каждой мы сделаем O(n) операций просмотра смежных ребер для выбора минимального исходящего. Этого же количества для каждой вершины, в случае конденсации, хватит, чтобы построить ребра для новой вершины.

      Замечу, что здесь я строил дерево, ребра которого направлены к корню, а не от корня, но это не принципиально.

      Кажется, в статье "Finding Optimum Branchings", Networks, v.7, 1977, pp. 25–35. все это дело описано, но я мог что-то забыть. Еще отмечу, что иногда ищут branchings, иногда — arborescence, иногда — r-arborescence. Первое — ориентированный лес, второе — дерево с произвольным корнем, а последнее — дерево с фиксированным корнем. Все они сводятся друг к другу построением O(n + m) дополниткльных вершин и ребер, но новый вес ребра, в случае конденсации, в каждом случае может отличаться. В случае r-arborescence для выходящего ребра (u, v) он будет равен c(u, v) - c(u, w), где c(u, w) минимально при фиксированном u.