Przeskocz do treści

Delta mi!

Informatyczny kącik olimpijski

Zagadka

Tomasz Kulczyński

o artykule ...

  • Publikacja w Delcie: grudzień 2010
  • Publikacja elektroniczna: 16-01-2011

W tym kąciku przyjrzymy się zadaniu Zagadka, które pojawiło się na tegorocznych Potyczkach Algorytmicznych.

Przede wszystkim zauważmy, że powyższe wymagania ograniczające możliwości wyboru stolic możemy zamienić na zestaw zdań logicznych. Dla każdego miasta  math wprowadźmy zmienną logiczną math oznaczającą, czy dane miasto jest stolicą swojego województwa. Wówczas drogę łączącą miasta math i  math możemy rozumieć jako alternatywę math. Województwo interpretujemy natomiast jako zbiór alternatyw postaci math dla każdej pary różnych miast mathmath z tego województwa.

W ten sposób sprowadziliśmy zadanie do wybrania dla każdego miasta  math wartości zmiennej logicznej  math, tak aby zachodziły wszystkie wymienione wyżej alternatywy. (Jeżeli znajdziemy rozwiązanie, w którym pewne województwo nie ma żadnej stolicy, to w takim przypadku możemy dowolne jego miasto uznać za jego stolicę i nie zepsuje to znalezionego rozwiązania.) Jest to klasyczny problem 2-SAT, dla którego znany jest liniowy (dokładniej: liniowo zależny od liczby zmiennych i liczby alternatyw) algorytm. W przypadku naszego zadania oznacza to rozwiązanie w czasie math. Nie jest to jeszcze wynik satysfakcjonujący. Aby go poprawić, zagłębimy się w działanie algorytmu rozwiązującego problem 2-SAT, po czym spróbujemy go przyspieszyć dla tego konkretnego zadania.

Zauważmy, że każdą alternatywę math możemy zamienić na dwie implikacje: math oraz math. Zbudujemy zatem graf, którego wierzchołkami są math oraz  math dla wszystkich  math, a krawędziami – implikacje powstałe ze wszystkich naszych alternatyw. Chcemy dla każdego miasta  math wybrać dokładnie jeden z dwóch odpowiadających mu wierzchołków i uznać za prawdziwy, pamiętając przy tym o implikacjach. Nietrudno spostrzec, że w każdej silnie spójnej składowej takiego grafu wszystkie wierzchołki mają taką samą wartość logiczną. Jeśli utożsamimy wierzchołki należące do tych samych silnie spójnych składowych, otrzymujemy tzw. graf silnie spójnych składowych, w którym nie ma już cykli. Ten graf sortujemy topologicznie. Rozpatrujemy kolejno te silnie spójne składowe, z których wychodzą krawędzie tylko do już rozpatrzonych. Zauważmy, że jeśli math i  math są w tej samej silnie spójnej składowej, to math i  math także, gdyż jeśli z  math można dojść krawędziami do  math, to z  math można analogicznie dojść do  math, podobnie jeśli można dojść z  math do  math, to można z  math do  math (wynika to ze sposobu konstrukcji krawędzi z alternatyw). W takim razie, podczas rozpatrywania kolejnych składowych, jeśli napotykamy taką, której komplementarna nie została jeszcze rozpatrzona, ustalamy, że wszystkie wierzchołki tej składowej będą prawdziwe, a komplementarnej – fałszywe. W ten sposób dla każdej pary literałów mathmath zdecydujemy, który z nich jest prawdziwy, a wszystkie implikacje, a więc także alternatywy, będą spełnione (dlaczego?). Jedynym przypadkiem, gdy ta metoda nie działa, jest sytuacja, gdy dla pewnego  math, math i  math leżą w jednej silnie spójnej składowej. W takim przypadku w ogóle nie istnieje żadne rozwiązanie, gdyż implikacje są sprzeczne.

Widzimy, że główny koszt czasowy algorytmu jest generowany przez znajdowanie silnie spójnych składowych i grafu tychże oraz przez sortowanie topologiczne tego grafu. Wszystkie te operacje w standardowy sposób wykonujemy za pomocą dwóch przeszukiwań w głąb (DFS). Koszt jednego takiego przeszukiwania to math , gdzie math to liczba wierzchołków, a  math – liczba krawędzi grafu. math jest w naszym przypadku równe  math, a więc akceptowalne. Problemem jest math . Krawędzie odpowiadające niewygodnemu składnikowi  math są jednak rozmieszczone regularnie wewnątrz poszczególnych województw. Możemy zatem pamiętać dla każdego wierzchołka jedynie jego „normalnych” sąsiadów, natomiast krawędzie wynikające z przynależności do województwa wyznaczać na bieżąco, w razie potrzeby. Będąc w dowolnym wierzchołku, możemy pójść w przeszukiwaniu grafu dowolną krawędzią z jego listy krawędzi lub też krawędzią z listy krawędzi województwa. Co do tych ostatnich, to jeśli zużywamy krawędź „wojewódzką” z  math do  math, możemy spokojnie założyć, że krawędzie „wojewódzkie” z  math do  math dla wszystkich  math są już niepotrzebne, i o nich zapomnieć. Jest tak, gdyż wierzchołek math odwiedzamy raz, idąc z  math, a wszystkie pozostałe krawędzie do niego prowadzące już nam nie posłużą w przeszukiwaniu. Jeśli rozmiar województwa to  math , to zamiast math  krawędzi dla tego województwa pamiętamy tylko math  końców tych krawędzi i każdy koniec wykorzystujemy dokładnie raz, przy pierwszej nadarzającej się okazji.

W ten sposób wykonujemy przeszukiwanie DFS w rozważanym grafie w czasie math . Całe rozwiązanie ma złożoność czasową i pamięciową math .