$ Паросочетания vb = [Ваня] sk = [Сережа.K] sm = [Сережа.М] # $sk$ C/C++ ## static int x = 0; ## inline ## random\_shuffle ## printf("%-*s : %.2f\n", 20, "abc", sqrt(2.0)) ## scanf("%d") → getchar(), readUInt() # $sk$ Паросочетание ## Определения: mathcing, cover, independent set, global cut ## min cover ≥ max matching ## Лемма для произвольного графе: паросочетание не максимально ⇒ существует дополняющий чередующийся путь ## Для доказательства леммы изучаем симметрическую разность с максимальным паросочетанием. ## Научимся в двудольном графе искать дополняющий чередующийся путь за O(E) ## Реализация: dfs, used[вершина первой доли], pair[вершина второй доли] ## Простой алгоритм за O(VE): пока есть путь, ищем путь ## Алгоритм Куна за O(VE): от каждой вершины запускаем один раз dfs ## Жадная инициализация: можно как минимум половину паросочетания построить за O(E) ## A^{+}, A^{-}, B^{+}, B^{-}: по готовому паросочетанию за O(E) ищем cover, independent set ## Паросочетание, которое максимизирует суммарный вес вершин первой доли (док-во: матроид) ## Еще паросочетание умеют искать за O(EqsrtV): алгоритм Хопкрофта-Карпа ## Рандомизированный алгоритм поиска паросочетания в произвольном графе # $sk$ Задачи про паросочетания ## [matching] Доминошки на доске с дырками ## [matching] Taxi: покрытие ацикличного графа путями ## [independent] Максимальная клика (или антиклика) в двудольном графе ## [cover] Замощение грида минимальным числом палок 1xN *## В каком случае ребро лежит в каком-то максимальном паросочетании? *## В каком случае ребро лежит в любом максимальном паросочетании? ## Стабильное паросочетание (мальчики предлагают, девочки отказываются)