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

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

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

struct cmp { bool operator()(int a, int b) const { return d[a] < d[b];} };

здесь массив d[] хранит кратчайшее расстояние к вершине i;

Когда я попробовал добавить в контейнер число b, такое что d[a]==d[b] и a!=b, то ничего не произошло (то есть нужное число не добавилось в контейнер а релаксация вершины прошла) и как последствие неверная работа алгоритма :(

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

P.S.: За ранние всем спасибо :)

UPD: Проблема решена, но вопрос реализации с помощью других структур остается открыт.

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

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

multiset

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

    У multiset реализация такая же как в обычном set?

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

      erase по значению удаляет все вхождения, а не только одно

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

        Ясно, спасибо, но для Дейкстры такое не подходит :(

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

          Можно делать erase по итератору, он удаляет единичный элемент. Но здесь есть свои тонкости с нахождением нужного элемента, так что, по видимому, вариант, предложенный dalex'ом наиболее подходящий.

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

Можно использовать priority_queue, вроде побыстрее (не знаю), но там нельзя удалять. На e-maxx написано, как это обойти.
Я всегда писал set с парами, и все работало хорошо. Но однажды наткнулся на задачу с Дейкстрой на informatics.msk.ru (что-то мне подсказывает, что Вы решаете именно ее), в которой set все-таки не вошел. Впрочем, Treap все поправил.

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

    Нет, наткнулся на проблему решая эту задачу: Задача

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

      По поводу этой задачи — у меня по ней Дейкстра отработал за 0.041. Конкретно с ней проблем с быстродействием быть не должно)

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

      Хмм, обычная квадратная Дейкстра -- 0,012.
      Можно ваш код посмотреть, что там не так, наверное.

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

        Вот исходник: 6951989. Извините, но более гуманного способа показать код не придумал.

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

          paste.ubuntu.com

        • »
          »
          »
          »
          »
          10 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          vector < vector < pair <int, int> > > g(n*m);
          

          Такое чувство, что данная строчка хорошенько так влияет на время работы. Да и вообще явно хранить граф в некоторых задачах, включая эту, бывает муторнее, чем неявно.

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

          Кстати, Ваш код с парами замечательно прошел.

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

      лол, задача на дп.

»
10 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
if (d[a] == d[b]) return a < b;
return d[a] < d[b];
  • »
    »
    10 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Спасибо огромное, это работает :)

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

      а теперь я не понял, в чём была проблема? просто у pair такой же компаратор.

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

        Нет, для pair можно использовать обычный компаратор (std::less) set <pair <int, int> > // вес — ребро

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

          а теперь я не понял смысл этого коммента.

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

            В set -е идет сортировка по первому int в паре (то есть по весу ребер к вершинам), а второй int — это сама вершина. Поробние: Your text to link here...

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

              ты меня не понял или просто издеваешься. я понимаю, как реализовывается дийкстра через set< pair >, я не понял, почему ТЕБЕ не нравится этот способ. с топике ты написал, что из-за времени, но ведь у pair такой же по сути компаратор, как у dalex'a, а он тебе угодил.

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

                Я просто не понял... На е-maxx'e написано что если избавится от pair то будет быстрее (а поскольку я только учи алгоритмы то питаюсь запоминать самые быстрые), но как показал сайт они идентичные по времени, но с pair "надежные".