Przeskocz do treści

Delta mi!

Informatyczny kącik olimpijski

Dziurawa szachownica

Tomasz Idziaszek i Paweł Parys

o artykule ...

  • Publikacja w Delcie: sierpień 2012
  • Publikacja elektroniczna: 31-07-2012

W tym miesiącu omówimy zadanie, które pojawiło się w pierwszej edycji konkursu Potyczki Algorytmiczne, w roku 2005.

obrazek

Zadanie. Dana jest szachownica o  math  wierszach i  math  kolumnach math , mająca taki feler, że na niektórych jej polach znajdują się dziury. Obliczono, na ile sposobów można na tej szachownicy rozstawić math  wież tak, by żadna z wież nie stała na dziurawym polu i nie groziła zbiciem innej (tzn. w każdej kolumnie może stać co najwyżej jedna wieża, a w każdym wierszu stoi dokładnie jedna wieża). Należy wskazać te pola szachownicy, w których można wywiercić dodatkowe dziury tak, aby powyższa liczba ustawień nie zmieniła się. Przykładowa szachownica została przedstawiona na poniższym rysunku. Krzyżykami oznaczono dziurawe pola, zaś kolorem wyróżniono jedno z dwóch prawidłowych rozmieszczeń wież. Dodatkowe dziury można zrobić na polach b1 oraz a2.

Zapewne niektórzy Czytelnicy od razu zorientują się, że pod płaszczykiem terminologii szachowej kryje się problem, który możemy sprowadzić do znajdowania skojarzeń w grafach dwudzielnych. Tak jest istotnie. Rozważmy bowiem graf dwudzielny math  o  math  wierzchołkach: wierzchołki ze zbioru math  będą odpowiadać wierszom szachownicy, natomiast wierzchołki ze zbioru math – kolumnom. Dwa wierzchołki math i  math  łączymy krawędzią wtedy, gdy na przecięciu wiersza math i kolumny math nie ma dziury. W takiej sytuacji poprawne rozstawienie wież na szachownicy odpowiada skojarzeniu rozmiaru math w grafie math  Treść zadania możemy więc przeformułować następująco: należy znaleźć te krawędzie w grafie math  które nie należą do żadnego skojarzenia rozmiaru math

To prowadzi nas do pierwszego rozwiązania. Dla każdego niedziurawego pola szachownicy math wykonujemy następujące sprawdzenie: stawiamy na nim wieżę i próbujemy rozstawić math  wież na pozostałej części szachownicy, uruchamiając algorytm wyznaczania najliczniejszego skojarzenia w grafie dwudzielnym. Rozwiązanie to można przyspieszyć: zamiast za każdym razem od nowa znajdować najliczniejsze skojarzenie, możemy zacząć od poprzednio znalezionego. W tym celu usuwamy wieże z wiersza math i kolumny math Za każdym razem wystarczy zatem ustawić co najwyżej dwie brakujące wieże, czyli znaleźć co najwyżej dwie ścieżki powiększające skojarzenie. Złożoność czasowa to math

Podamy teraz lepsze rozwiązanie. Na początek znajdujemy w grafie math  dowolne skojarzenie rozmiaru math (jeśli takie skojarzenie nie istnieje, to można wywiercić dziury we wszystkich polach). Tworzymy teraz graf skierowany math  o takim samym zbiorze wierzchołków co math  i następujących krawędziach:

(1)
krawędzie, które w grafie math  należały do znalezionego skojarzenia, kierujemy od math do math
(2)
pozostałe krawędzie z  math  kierujemy od math do math
(3)
dodajemy krawędzie z wszystkich skojarzonych wierzchołków w  math do wszystkich nieskojarzonych wierzchołków w  math

Następnie znajdujemy silnie spójne składowe w grafie math  Okazuje się, że krawędzie, które nie należą do żadnego skojarzenia rozmiaru math w grafie math  to te krawędzie typu (2) w grafie math  które łączą dwie różne silnie spójne składowe. Spróbujmy to uzasadnić.

Stosunkowo łatwo wykazać, że pozostałe krawędzie typu (2) należą do pewnego skojarzenia. Rozważmy taką krawędź math która leży wewnątrz pewnej silnie spójnej składowej, zatem leży ona na pewnym cyklu. Cykl ten może składać się z naprzemiennych krawędzi typu (1) i (2) lub może zawierać krawędzie typu (3). W pierwszym przypadku do skojarzenia zamiast krawędzi typu (1) z cyklu bierzemy krawędzie typu (2) i uzyskujemy nowe skojarzenie zawierające krawędź math W drugim przypadku rozważamy najdłuższą ścieżkę cyklu zawierającą math a niezawierającą krawędzi typu (3). Ścieżka ta składa się na zmianę z krawędzi typu (1) i (2) oraz zaczyna się w wierzchołku nieskojarzonym, a kończy w skojarzonym. Znowu więc odwrócenie rolami krawędzi typu (1) i (2) załatwia sprawę.

Rozważmy teraz krawędź math (z  math do math ) typu (2), która łączy w  math  dwie różne silnie spójne składowe. Wszystkie wierzchołki w  math  są skojarzone, niech więc math  będzie wierzchołkiem skojarzonym z  math Oznaczmy przez math zbiór tych wierzchołków, z których można dojść do wierzchołka math (w szczególności math ). Wszystkie wierzchołki w  math są skojarzone, w przeciwnym przypadku taki nieskojarzony wierzchołek musiałby być w  math zatem prowadziłaby do niego krawędź typu (3) z  math czyli krawędź math leżałaby wewnątrz silnie spójnej składowej. Ponadto zbiory math i  math  są równoliczne i skojarzone między sobą oraz żaden z wierzchołków math  nie jest połączony z wierzchołkami spoza math Innymi słowy, wszystkie wierzchołki z  math są potrzebne do skojarzenia wierzchołków z  math  zatem w najliczniejszym skojarzeniu żaden nie może być skojarzony przez krawędź math To kończy dowód.

Na złożoność czasową rozwiązania składa się znalezienie najliczniejszego skojarzenia w  math  i wyznaczenie silnie spójnych składowych w  math  Pierwszy krok można wykonać w czasie math  korzystając z metody ścieżek naprzemiennych, lub w czasie math  korzystając z algorytmu Hopcrofta–Karpa.

Drugi krok można wykonać za pomocą dwóch przeszukań grafu w głąb. Jako ćwiczenie dla Czytelnika pozostawiamy pokazanie, że można to zrobić w czasie math  Kłopot stanowią krawędzie typu (3), których może być rzędu math należy zatem wykorzystać ich regularną strukturę.