Введем горигозтальную ось, на которой будем откладывать

advertisement
Решение
Введем горизонтальную ось, на которой отложим станции прицепки/отцепки вагонов. Тогда
каждому вагону можно поставить в соответствие интервал оси от станции, на которой его надо
прицепить, до станции, на которой его надо отцепить. Разные вагоны будем изображать
интервалами на разных горизонтальных прямых.
Нам необходимо научиться прицеплять вагоны к
V1
поезду так, чтобы их можно было отцепить на A
V2
нужной станции (или определять, что требуемое
невозможно). Очевидно можно считать, что на
V1
каждой
станции
сначала
отцепляются
все
необходимые
вагоны,
а
потом
требуемые B
V2
прицепляются. Т.е. на нашей оси моменты отцепки
на некоторой станции строго предшествуют
V1
моментам прицепки. В предположении, что и начала,
V
2
и концы интервалов различны, всего существует три C
принципиально различных способа взаимного
расположения пары вагонов V1 и V2 (см. рис.).
Рассмотрим далее решение задачи для каждого из трех приведенных в условии случаев.
1) Наличие в составе хотя бы одного вагона, который прицепляется на первой станции и
отцепляется на последней. Тогда каждый из остальных вагонов прицепляется и отцепляется либо
только в начале состава, либо только в конце него. В этом случае два вагона могут быть
прицеплены с одной стороны и не мешать отцепится друг другу, если они распологаются по
варианту B или С. Вагоны же, схема прицепки/отцепки которых соответствует варианту A,
должны прицепляться с разных сторон, иначе корректно отцепить первый из них будет
невозможно.
Для построения схемы прицепки таких вагонов можно предложить следующее решение.
Рассмотрим граф, вершины которого — вагоны, а ребрами соединены пары вагонов с взаимным
расположением по варианту A.
Решением задачи будет раскраска вершин этого графа в два цвета (цвет соответствует месту
прицепки вагона — в начало или в конец состава) такая, при которой ребра графа будут соединять
вершины разного цвета. Построение такой раскраски соответствует проверке графа на
двудольность и реализовать ее можно с помощью любого обхода графа (например, в ширину или
глубину). В процессе такого обхода мы проверяем, что все вершины, смежные с текущей и
раскрашенные ранее, имеют цвет, отличный от цвета текущей вершины (если это не так, то наша
задача решения не имеет) и помечаем все не раскрашенные вершины, смежные с текущей,
противоположным цветом. Трудоемкость подобного алгоритма не превосходит O(N2).
2) Случай, когда на каждой станции прицепляется не более одного вагона.
В отличие от предыдущего случая здесь вагон может прицепиться к составу с одной стороны, а
отцепиться — с другой.
Будем под схемой понимать расстановку на концах всех интервалов 0 или 1, обозначающих с
какой стороны состава происходит прицепка/отцепка соответствующего интервалу вагона.
Опишем все условия, которые налагаются на схему. Так как при фиксированной схеме мы знаем, с
какой стороны мы собираемся отцеплять конкретный вагон, то мешать его отцеплению может
какой-то другой вагон. Поэтому все необходимые и достаточные условия на реализуемость схемы
являются условиями на пары вагонов.
Если тип расположения вагонов А, то первый отцепляется и второй прицепляется с разных сторон.
Если тип расположения вагонов В, то внутренний прицепляется и отцепляется с одной стороны.
Если тип расположения вагонов С, то никаких условий нет.
Вагоны, отцепляющиеся на одной станции не мешают друг другу (напомним, что прицепляться на
одной станции несколько вагонов не могут).
Тогда получаем решение, аналогичное решению для пункта 1).
Рассмотрим граф, вершинами коротого будут уже концы интервалов. Для каждой пары вагонов,
если тип расположения
 А (т.е. V11 < V21 < V12 < V22 , где верхний индекс обозначает конец интервала), то проведем
ребро между V21 и V12 и напишем на нем 1.
 В (т.е. V21 < V11 < V12 < V22), то проведем ребро между V11 и V12 и напишем на нем 0.
 С (т.е. V11 < V12 ≤ V21 < V22), то ничего не делаем.
Решением задачи будет раскраска вершин графа в два цвета такая, что вершины, соединенные
ребром с 0, окрашены одинаково, а с 1 — в разные цвета. Эта раскраска строится (или
определяется невозможность ее построения) аналогично пункту 1) обходом графа в ширину или в
глубину.
Решение можно интерпретировать и по-другому. Выделим по одной вершине в каждой
компоненте связности нашего взвешенного графа и подсчитаем расстояние (сумму значений на
ребрах) от этих вершин до всех остальных в соответствующих компонентах связности. Тогда
искомый цвет раскраски вершины можно рассматривать как сумму значений на пути до нее от
фиксированной вершины, взятую по модулю 2. О невозможности решения задачи говорит в
данном случае наличие цикла с нечетной суммой весов на входящих в него ребрах.
3) Возможно прицеплять несколько вагонов сразу на одной станции.
Прежде всего избавимся от одинаковых вагонов и оставим в рассмотрении только один из них,
разумно полагая, что остальные прицепляются и отцепляются точно так же (очевидно на
существование схемы это не повлияет).
Построим граф, аналогичный пункту 2), соединяя ребрами только несовпадающие концы
интервалов. Если в таком графе есть цикл с нечетной суммой (напомним, что под длиной здесь
понимается сумма значений на ребрах, входящих в цикл), то схемы не существует, т.е. задача не
разрешима.
Осталось рассмотреть пары вагонов с совпадающими левыми концами инвервалов. В зависимости
от того, как мы выберем порядок их прицепки, будут разные условия на пары (т.к. получатся
разные типы расположения интервалов для соответствующих вагонов). Сместим концы
совпадающих интервалов так, чтобы все они стали различны. Покажем, что это можно сделать
так, что в графе не появятся циклы с нечетной суммой.
Будем рассматривать вагоны по возрастнию длин интервалов и в случае необходимости двигать
концы. Рассмотрим вагон V1.
a) Если между вершинами V11 и V12 есть путь с нечетной суммой, то V11 сдвинем чуть влево, а V12
—чуть вправо. Тогда добавление новых ребер не приведет к образованию новых путей. Т.к. есть
путь с нечетной суммой и нет противоречий, то есть ребро из вершины V11, причем не в вершину
V12, т.е. существует какой-то вагон V0, что V01 < V11 < V02 < V12.
Новые ребра добавляются только для вагонов с одинаковыми левыми концами интервалов.
Рассмотрим вагон V с таким же началом, что и V1. Тогда после смещения концов V1 имеем: V01 <
V11 < V1 < V02 < V12< V2. Т.е. в графе возникает новое ребро из V12 в V1 с весом 1, но ранее между
этими вершинами уже существовал путь с нечетной суммой. Аналогично для остальных вагонов
получаем, что противоречий не возникнет.
б) Если пути с нечетной суммой нет, то будем считать, что V11 сдвинута чуть влево, а V12 — чуть
вправо. Тогда все новые ребра, которые возможно возникнут, — это только ребра, соединяющие
V11 и V12. Они помечены 0, что не приведет к образование циклов с нечетной суммой.
На этом рассуждении построен следующий алгоритм.
Прежде всего отождествим одинаковые вагоны сохранив для вывода их номера.
Для каждой станции заведем два списка — первые и последние. В список первые будем добавлять
элементы в конец, а в список последние — в начало.
Построим описанный выше граф, учитывая пока только взаимное расположение интервалов с
несовпадающими левыми концами. Если в нем есть циклы с нечетной суммой, то решения нет.
Иначе построим схему прицепки вагонов так. Будем рассматривать вагоны с совпадающими
левыми концами интервалов последовательно в порядке возрастания их времени в пути,
производя следующую операцию:

если между вершинами графа, соответствующими концам интервала для рассматриваемого
вагона, нет пути с нечетной суммой, то данный вагон добавляем в список первые для станции,
на которой он должен прицепиться;
 если между вершинами графа, соответствующими концам интервала, есть путь с нечетной
суммой, то данный вагон добавляем в список последние для станции, на которой он должен
прицепиться;
 если пути не было вообще, то перестраиваем граф, добавив ребро, помеченное 0, между
концами интервала.
Как и ранее, место прицепки конкретного вагона будет определяться четностью длины пути
между вершиной графа, соответствующей началу интервала для этого вагона и некоторой
выделенной вершиной в соответствующей компоненте связности графа. Т.к. на каждом шаге граф
представляет из себя несколько компонент связанности, каждая из которых состоит из двух долей,
то проведение ребра приводит к объединению двух компонент. Таким образом для реализации
алгоритма на этом графе достаточно уметь хранить такую структуру данных, как
непересекающиеся множества с реализованной операцией их объединения. При формировании
ответа для каждой станции выводим сначала список первые (с первого элемента в списке до
последнего), затем список последние (с первого элемента в списке до последнего).
Как и ранее, сложность алгоритма не превосходит O(N2) (это сложность обхода в ширину, все
остальные этапы имеют сложность не выше O(NlogN)).
Download