stanczyk

download stanczyk

of 303

Transcript of stanczyk

Uniwersytet Warszawski Wydzia Matematyki, Informatyki i Mechaniki

Piotr StaczykNr albumu: 209291

Algorytmika praktyczna w konkursach InformatycznychPraca magisterska na kierunku INFORMATYKA w zakresie ALGORYTMIKA

Praca wykonana pod kierunkiem dra hab. Krzysztofa Diksa Instytut Informatyki

Czerwiec 2006

Owiadczenie kierujacego pracaOwiadczam, e niniejsza praca zostaa przygotowana pod moim kierunkiem i stwierdzam, e spenia ona warunki do przedstawienia jej w postepowaniu o nadanie tytuu zawodowego.

Data

Podpis kierujacego praca

Owiadczenie autora (autorw) pracywiadom odpowiedzialnoci prawnej owiadczam, e niniejsza praca dyplomowa zostaa napisana przeze mnie samodzielnie i nie zawiera treci uzyskanych w sposb niezgodny z obowiazujacymi przepisami. Owiadczam rwnie, e przedstawiona praca nie bya wczeniej przedmiotem procedur zwiazanych z uzyskaniem tytuu zawodowego w wyszej uczelni. Owiadczam ponadto, e niniejsza wersja pracy jest identyczna z zaaczona wersja elektroniczna.

Data

Podpis autora (autorw) pracy

StreszczenieBrak

Sowa kluczoweBrak

Dziedzina pracy (kody wg programu Socrates-Erasmus)11.3 Informatyka

Klasykacja tematycznaBrak

Spis treci1. Przedmowa . . . . . . . 1.1. Struktura ksiki . . a 1.2. Wymagania wstpne 1.3. Podzikowania . . . 1.4. Nagwki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 8 9 9 10 13 14 18 24 29 35 39 42 48 54 57 61 64 64 68 70 73 74 76 78 82 87 91 92 94 100 108 110 114 117

2. Algorytmy Grafowe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1. Struktura grafu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2. Przeszukiwanie grafu wszerz . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3. Przeszukiwanie grafu w gb . . . . . . . . . . . . . . . . . . . . . . . . . . . . a 2.4. Silnie spjne skadowe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5. Sortowanie topologiczne . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.6. Acykliczno . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.7. Dwuspjne skadowe, mosty i punkty artykulacji . . . . . . . . . . . . . . . . 2.8. cieka i cykl Eulera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.9. Minimalne drzewo rozpinajce . . . . . . . . . . . . . . . . . . . . . . . . . . a 2.10. Algorytm Dijkstry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.11. Algorytm Bellmana - Forda . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.12. Maksymalny przepyw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.12.1. Maksymalny przepyw metod Dinica . . . . . . . . . . . . . . . . . . a 2.12.2. Maksymalny przepyw dla krawdzi jednostkowych . . . . . . . . . . . 2.12.3. Najtaszy, maksymalny przepyw dla krawdzi jednostkowych . . . . . 2.13. Maksymalne skojarzenie w grae dwudzielnym . . . . . . . . . . . . . . . . . 2.13.1. Dwudzielno grafu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.13.2. Maksymalne skojarzenie w grae dwudzielnym w czasie O(n (n + m)) 2.13.3. Maksymalne skojarzenie w grae dwudzielnym w czasie O((n + m) n) 2.13.4. Najdrosze skojarzenie w grae dwudzielnym . . . . . . . . . . . . . . 3. Geometria obliczeniowa na paszczynie 3.1. Odlego punktu od prostej . . . . . . . 3.2. Powierzchnia wielokta . . . . . . . . . . a 3.3. Przynaleno punktu . . . . . . . . . . 3.4. Punkty przecicia . . . . . . . . . . . . . 3.5. Trzy punkty okrg . . . . . . . . . . a 3.6. Wypuka otoczka . . . . . . . . . . . . . 3.7. Sortowanie ktowe . . . . . . . . . . . . a 3.8. Para najbliszych punktw . . . . . . . 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4. Kombinatoryka . . . . . . . . . . . . . . . . . . . . . . . . 4.1. Permutacje w kolejnoci antyleksykogracznej . . . . . 4.2. Permutacje minimalne transpozycje . . . . . . . . . 4.3. Permutacje minimalne transpozycje ssiednie . . . a 4.4. Wszystkie podzbiory zbioru . . . . . . . . . . . . . . . 4.5. Podzbiory k-elementowe w kolejnoci leksykogracznej 4.6. Podziay zbioru minimaln liczb zmian . . . . . . . . a a 4.7. Podziay liczby w kolejnoci antyleksykogracznej . . . 5. Teoria liczb . . . . . . . . . . . . . 5.1. Dwumian Newtona . . . . . . . 5.2. Najwikszy wsplny dzielnik . . 5.3. Odwrotno modularna . . . . 5.4. Kongruencje . . . . . . . . . . . 5.5. Szybkie potgowanie modularne 5.6. Sito liczb pierwszych . . . . . . 5.7. Lista liczb pierwszych . . . . . 5.8. Test pierwszoci . . . . . . . . . 5.9. Arytmetyka wielkich liczb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

123 123 125 127 129 131 132 134 137 137 139 142 144 146 148 149 151 154 171 172 175 177 180 182 185 188 192 203 203 206 207 213 217 220 221 222 224 225 226 231 231 232 235 238

6. Struktury danych . . . . . . . . . . . . . . . . . . . . . . 6.1. Struktura danych do reprezentacji zbiorw rozcznych a 6.2. Drzewa poszukiwa binarnych . . . . . . . . . . . . . . 6.2.1. Drzewa maksimw . . . . . . . . . . . . . . . . 6.2.2. Drzewa licznikowe . . . . . . . . . . . . . . . . 6.2.3. Drzewa pozycyjne . . . . . . . . . . . . . . . . 6.2.4. Drzewa pokryciowe . . . . . . . . . . . . . . . . 6.3. Binarne drzewa statyczne dynamicznie alokowane . . . 6.4. Wzbogacane drzewa binarne . . . . . . . . . . . . . . . 7. Algorytmy tekstowe . . . . . . . . . . . . . . . . . . 7.1. Algorytm KMP . . . . . . . . . . . . . . . . . . . 7.2. Minimalny okres sowa . . . . . . . . . . . . . . . 7.3. KMP dla wielu wzorcw (algorytm Bakera) . . . 7.4. Promienie palindromw w sowie . . . . . . . . . 7.5. Drzewa suksowe . . . . . . . . . . . . . . . . . . 7.5.1. Liczba wystpie wzorca w tekcie . . . . a 7.5.2. Liczba rnych podsw sowa . . . . . . . 7.5.3. Najdusze podsowo wystpujce n razy . a 7.6. Maksymalny leksykogracznie suks . . . . . . . 7.7. Rwnowano cykliczna . . . . . . . . . . . . . . 7.8. Minimalna leksykograczna cykliczno sowa . . 8. Algebra liniowa . . . . . . . . 8.1. Eliminacja Gaussa . . . . . 8.1.1. Eliminacja Gaussa w 8.1.2. Eliminacja Gaussa w 8.2. Programowanie liniowe . . . . . . . Z2 Zp . . . . . . . . . . . . . . . . . 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

9. Elementy strategii podczas zawodw . . . . . . . . . . . . . . . . . . . . 9.1. Szacowanie oczekiwanej zoonoci czasowej . . . . . . . . . . . . . . . . 9.2. Strategia pracy w druynie . . . . . . . . . . . . . . . . . . . . . . . . . 9.3. Szablon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.4. Makele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.5. Parametry kompilacji programw . . . . . . . . . . . . . . . . . . . . . . 9.5.1. -Wec++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.5.2. -Wformat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.5.3. -Wshadow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.5.4. -Wsequence-point . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.5.5. -Wunused . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.5.6. -Wuninitialized . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.5.7. -Woat-equal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.6. Nieustanny Time - Limit . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.6.1. Wczytywanie wejcia . . . . . . . . . . . . . . . . . . . . . . . . . 9.6.2. Kompilacja z optymalizacjami i generowanie kodu maszynowego 9.6.3. Lepsze wykorzystanie pamici podrcznej . . . . . . . . . . . . . 9.6.4. Preprocessing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.Rozwizania zada . . . . . . . . . . . . . a 10.1. Algorytmy Grafowe . . . . . . . . . . . . 10.1.1. Mrwki i biedronka . . . . . . . . 10.1.2. Komiwojaer Bajtazar . . . . . . 10.1.3. Drogi . . . . . . . . . . . . . . . 10.1.4. Spokojna komisja . . . . . . . . . 10.1.5. Wirusy . . . . . . . . . . . . . . 10.1.6. Linie autobusowe . . . . . . . . . 10.1.7. Przemytnicy . . . . . . . . . . . 10.1.8. Skoczki . . . . . . . . . . . . . . 10.2. Geometria obliczeniowa na paszczynie 10.2.1. Akcja komandosw . . . . . . . . 10.2.2. Pomniki . . . . . . . . . . . . . . 10.2.3. Otarze . . . . . . . . . . . . . . 10.3. Kombinatoryka . . . . . . . . . . . . . . 10.3.1. Liczby permutacyjnie - pierwsze 10.4. Teoria liczb . . . . . . . . . . . . . . . . 10.4.1. Bilard . . . . . . . . . . . . . . . 10.4.2. Wyliczanka . . . . . . . . . . . . 10.4.3. acuch . . . . . . . . . . . . . . 10.5. Struktury danych . . . . . . . . . . . . . 10.5.1. Mapki . . . . . . . . . . . . . . 10.5.2. Kodowanie permutacji . . . . . . 10.5.3. Marsjaskie mapy . . . . . . . . 10.5.4. Puste prostopadociany . . . . . 10.6. Algorytmy tekstowe . . . . . . . . . . . 10.6.1. Szablon . . . . . . . . . . . . . . 10.6.2. MegaCube . . . . . . . . . . . . 10.6.3. Palindromy . . . . . . . . . . . . 10.6.4. Punkty . . . . . . . . . . . . . . 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

245 245 247 250 250 251 251 253 254 255 258 259 260 260 261 263 265 266 269 269 269 270 270 271 271 272 272 273 273 273 274 274 274 274 275 275 275 276 276 276 277 277 277 278 278 279 279 279

10.7. Algebra liniowa . . . . 10.7.1. Taniec . . . . . 10.7.2. Sejf . . . . . . 10.7.3. Szalony malarz

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

280 280 281 281

A. Nagwki Eryka Kopczyskiego . . . . . . . . . . . . . . . . . . . . . . . . . . 283 B. Sposoby na sukces w zawodach . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 C. Zbir zada na programowanie dynamiczne . . . . . . . . . . . . . . . . . . 293 D. Zbir zada na programowanie zachanne . . . . . . . . . . . . . . . . . . . . 295 Bibliograa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297

6

Rozdzia 1

PrzedmowaNajstarszym akademickim konkursem programistycznym jest International Collegiate Programming Contest organizowany przez Association for Computing Machinery (w skrcie ACM, ocjalna strona konkursu http://icpc.baylor.edu/icpc/ ). Pierwsze zawody naowe odbyy si 2 lutego 1977 roku w Atlancie, w Stanach Zjednoczonych (stan Georgia). Na pocztku lat dziewidziesitych w eliminacjach do tego konkursu brao udzia okoo 400 a a druyn, z ktrych 25 kwalikowao si co roku do nau. Dzi o 70 - 80 miejsc w naach walczy ponad 4000 druyn z 1600 uczelni caego wiata. Wzrost liczby uczestnikw wiadczy o ogromnej popularnoci konkursu, ktrej towarzyszy zwikszajcy si stopie przygotowania a druyn oraz trudno zada. wiatowej rangi konkursem, organizowanym dla uczniw szk rednich, jest Olimpiada Informatyczna (strona konkursu http://olympiads.win.tue.nl/ioi/ ), ktra zostaa po raz pierwszy zorganizowana w 1989 roku. W konkursie tym bierze udzia po czterech reprezentantw z kadego kraju, wybieranych w ramach olimpiad narodowych. Oprcz tych, cieszcych a si wieloletni tradycj konkursw, powstaje wiele nowych, takich jak TopCoder, Google Code a a Jam czy Imagine Cup. Udzia w konkursach dla uczniw oraz studentw staje si nieodzownym elementem nauki algorytmiki. Nieustannie podwyszajcy si poziom konkursw przynosi ze sob rne a a metodologie przygotowywania si do zawodw oraz specjalne techniki pisania programw. Ich celem jest minimalizowanie czasu potrzebnego na rozwizanie zadania, przy jednoczea snym eliminowaniu jak najwikszej liczby powstajcych bdw. Ze wzgldu na ograniczony a czas trwania konkursw, jego uczestnicy nie mog sobie pozwoli na wymylanie rozwiza a a wszystkich zada od samego pocztku. W wielu przypadkach musz wykorzystywa pomysy a a zastosowane w podobnych zadaniach, rozwizywanych ju wczeniej, co pozwala im zaoszcza dzi troch czasu. Ksika ta jest swego rodzaju podrcznikiem do algorytmiki. Nie zawiera ona jednak a wnikliwego opisu algorytmw wraz z ich analiz zoonoci oraz dowodem poprawnoci. Jest a to kolekcja implementacji rnych, bardzo przydatnych podczas zawodw algorytmw oraz zbir zada pozwalajcy na przewiczenie ich wykorzystania w praktyce. a Znaczc cz grona czytelnikw stanowi bd zapewne osoby zainteresowane zwika a a szeniem swoich umiejtnoci w zakresie szybkiego implementowania zada algorytmicznych w jzyku C++. Lektura ta na pewno wpynie pozytywnie na szybko rozwizywania zada a podczas takich konkursw jak Olimpiada Informatyczna. Uyteczno tej ksiki bdzie tym a wiksza podczas konkursw typu ACM ICPC, podczas ktrych dozwolone jest korzystanie z literatury. Wiele algorytmw z tej ksiki moe by po prostu przepisanych do implementoa wanych podczas zawodw programw. Prezentowane tutaj algorytmy zostay tak napisane, 7

aby ich adaptacja, w celu wykorzystania w rnych zadaniach, bya jak najprostsza, a jednoczenie ich kod rdowy jak najkrtszy. Pozycja ta moe suy nie tylko zawodnikom w poczeniu z ksik dotyczc poda a a a a staw algorytmiki, tak jak Wprowadzenie do algorytmiki [WDA], moe take stanowi doskoa nay sposb nauki od podstaw, czcy w sobie teoretyczn analiz algorytmw, z podeja a a ciem bardziej praktycznym, opisanym w tej ksice. Nauk tak w istotny sposb uatwi a a a liczne odwoania do literatury. Pomys na napisanie ksiki narodzi si podczas treningw mojego zespou Warsaw a Predators, do zawodw ACM ICPC. W czasie wielu sesji treningowych tworzylimy i rozbudowywalimy nasz biblioteczk algorytmiczn, w ktrej umieszczalimy implementacje a a najczciej wykorzystywanych w trakcie zawodw algorytmw i struktur danych. Ksik t a mona okreli mianem szczegowej dokumentacji do biblioteczki algorytmicznej druyny Warsaw Predators. Mam nadziej e materiay w niej zawarte pomog wielu osobom w przya gotowaniach do zawodw.

1.1. Struktura ksiki aKsika zostaa podzielona na siedem rozdziaw, w ktrych omwione s algorytmy z ra a nych dziedzin algorytmiki: teoria grafw, geometria obliczeniowa, kombinatoryka, teoria liczb, struktury danych, algorytmy tekstowe oraz algebra liniowa. W kadym z tych rozdziaw, przedstawione s rne algorytmy wraz z ich implementacjami, pochodzcymi z biblioteczki a a algorytmicznej. Ich omwienie ma na celu przyblienie problematyki poruszanego zagadnienia oraz zaprezentowanie sposobu wykorzystania algorytmw w zadaniach. W celu zapoznania si z dowodami poprawnoci, czy dokadn analiz zoonoci, naley siga do literatury, do a a ktrej odwoania umieszczone s w rnych miejscach ksiki. a a W dziale dodatkw znajduje si rozdzia dotyczcy programowania dynamicznego oraz a zachannego. Z uwagi na fakt, i z tymi dwoma technikami nie wi si specyczne struka a tury danych ani algorytmy (rozwizania zada bazujcych na programowaniu dynamicznym, a a czy zachannym - wykorzystuj algorytmy z rnych dziedzin), zatem rozdzia ten nie zaa wiera adnych przydatnych implementacji, lecz odwoania do wielu zada, na ktrych mona wiczy umiejtno stosowania tych metod w praktyce. W dodatkach umieszczone s rwnie obserwacje oraz rady pochodzce od wielu zawoda a nikw wiatowej klasy. Lektura tego rozdziau moe okaza si niezwykle cenna, gdy zawarte w nim informacje pomagaj unikn wielu problemw podczas przygotowa do zawodw. a a W poszczeglnych rozdziaach ksiki umieszczone s zadania, ktrych rozwizanie wie a a a a si z omawianym algorytmem. Zadania te s wybrane w taki sposb, aby algorytmy wymaa gane do ich rozwizania byy omwione, w miar moliwoci, w rozdziaach poprzedzajcych a a zamieszczone zadania. W ten sposb, ledzc w kolejnoci poszczeglne rozdziay ksiki, czya a telnik bdzie posiada wiedz potrzebn do rozwizania wszystkich zada. Wikszo z tych a a zada pochodzi z polskich konkursw informatycznych, takich jak Olimpiada Informatyczna, Potyczki Algorytmiczne czy Pogromcy Algorytmw. Programy stanowice ich rozwizania a a znajduj si na doczonej pycie. Dodatkowo, na kocu ksiki umieszczony jest rozdzia a a a zawierajcy wskazwki do wszystkich tych zada. Do kadego z nich znajduje si po kilka a podpowiedzi, ktre mog by pomocne podczas rozwizywania zadania kada kolejna a a wskazwka konkretyzuje pomys naszkicowany w poprzedniej. Dziki takiemu podejciu, jeli pocztkowe wskazwki okazuj si niewystarczajce do rozwizania zadania, mona pokusi a a a a si o przeczytanie kolejnych. Oprcz penych zada, w ksice znajduj si rwnie odwoania do innych zada, poa a 8

chodzcych z internetowych serwisw, umoliwiajcych automatyczn werykacj poprawnoa a a ci rozwiza. Czytelnik moe najpierw rozwiza samodzielnie zadanie, a nastpnie wysa a a je do systemu sprawdzajcego, w celu zwerykowania poprawnoci. Poniej znajduje si lista a serwisw internetowych, z ktrych wybrane zostay zadania do tej ksiki: a http://acm.sgu.ru/ Saratov State University :: Online Contester http://acm.uva.es/ Valladolid Programming Contest Site http://spoj.sphere.pl/ Sphere Online Judge

Wszystkie zadania zostay podzielone na trzy kategorie: zadania proste, redniej trudnoci oraz trudne. Trudno zada jest rzecz subiektywn. Podzia trudnoci uyty w ksice baa a a zuje na statystykach rozwiza, dostpnych w wymienionych wyej serwisach. Zadania trudne a charakteryzuj si stosunkowo ma liczb prb ich rozwizania, a wrd nich niewielka cz a a a a rozwiza okazuje si by poprawna. Zadania proste z kolei cechuj si wysokim odsetkiem a a zaakceptowanych rozwiza w stosunku do wszystkich nadesanych programw. a

1.2. Wymagania wstpneWszystkie przedstawione w tej ksice algorytmy s zaimplementowane w jzyku C++ a a jego znajomo jest nieodzowna do zrozumiaej analizy przedstawianych tu algorytmw. Konieczna jest rwnie znajomo biblioteki Standard Template Library (w skrcie STL), ktrej dokumentacj mona znale na stronie http://www.sgi.com/tech/stl/. Implementacja algorytmw wykorzystuje rne struktury danych oraz funkcje z tej biblioteki najwaniejsze z nich, to funkcje sort, swap i binary search oraz struktury danych vector, map i priority queue. Oprcz powyszych elementw, biblioteka STL zawiera wiele bardzo uytecznych narzdzi. Polecam zapoznanie si z ni, gdy moe ona w istotny sposb wpyn a a na efektywno rozwizywania zada algorytmicznych. a

1.3. PodzikowaniaOpisywana w tej ksice biblioteczka algorytmiczna zostaa stworzona wsplnie z moimi koa legami z zespou Warsaw Predators Markiem Cyganem i Marcinem Pilipczukiem. Chciabym rwnie podzikowa Tomaszowi Idziaszkowi, ktrego kilka chwytw programistycznych znalazo si w naszej biblioteczce oraz Erykowi Kopczyskiemu, ktry zgodzi si na opublikowanie zbioru swoich makr uywanych w konkursie TopCoder. Chciabym podzikowa Tomaszowi Czajce, Andrzejowi Gsienicy - Samkowi, Tomaszowi a Malesiskiemu, Krzysztofowi Onakowi oraz Marcinowi Stefaniakowi za wyraenie zgody na publikacj ich dobrych rad, ktre udzielili na prob prof. Krzysztofa Diksa swoim modszym kolegom, biorcym udzia w konkursie ACM ICPC na Uniwesytecie Warszawskim. a Wskazwki te zostay umieszczone w dziale Dodatki. Jednym z wyzwa, podczas gromadzenia materiaw do ksiki, by proces wybierania oda powiednich zada z rnych serwisw internetowych. Liczba dostpnych zada jest ogromna (w momencie pisania tego tekstu, serwis Valladolid Programming Contest Site zawiera ponad dwa tysice zada). Chciabym podzikowa Jakubowi Radoszewskiemu za udzielenie a cennych wskazwek dotyczcych wyboru zada. a Wielkie podzikowania nale si prof. Krzysztofowi Diksowi naszemu wykadowcy i a wielkiemu przyjacielowi, ktry wytrwale opiekowa si nami i stwarza warunki pozwalajce a 9

na efektywne przygotowania naszych druyn do zawodw. Ksika ta powstaa pod jego a opiek i nadzorem. a

1.4. NagwkiWszystkie programy w tej ksice s zaimplementowane w jzyku C++, z wykorzystaniem a a biblioteki STL. Poniewa podczas zawodw bardzo istotne jest, aby kody rdowe implementowanych programw byy jak najkrtsze, dlatego wielu zawodnikw stosuje pewne skrty dla najczciej wystpujcych w programach konstrukcji jzykowych. Podczas zawodw ACM a ICPC, w cigu piciogodzinnych sesji, do rozwizania jest 7 do 10 zada, zatem opaca si na a a pocztku zawodw przepisa zbir najwaniejszych instrukcji, a nastpnie wykorzystywa je a we wszystkich pisanych programach. Instrukcje te nazywamy mianem nagwkw zawieraj one zarwno list najczciej doczanych do programw bibliotek, jak i pewne operatory. a a Listing 1.1 przedstawia zbir podstawowych nagwkw pochodzcych z biblioteczki algoryta micznej mojego zespou wraz z komentarzami opisujcymi ich wykorzystanie. Na listingu 1.2 a przedstawione zostay te same nagwki po usuniciu komentarzy.Listing 1.1: Nagwki z komentarzami 01 #include 02 #include 03 #include 04 #include 05 #include 06 using namespace std; // Dwa z najczciej uywanych typw o dugich nazwach - ich skrcenie jest bardzo // istotne 07 typedef vector VI; 08 typedef long long LL; // W programach bardzo rzadko mona znale w peni zapisan instrukcj ptli. // Zamiast niej, wykorzystywane s trzy nastpujce makra: // FOR - ptla zwikszajca zmienn x od b do e wcznie 09 #dene FOR(x, b, e) for(int x=b; x=(e); x) // REP - ptla zwikszajca zmienn x od 0 do n. Jest ona bardzo // czsto wykorzystywana do konstruowania i przegldania struktur danych 11 #dene REP(x, n) for(int x=0; x b >> e; // Dodaj do grafu krawd skierowan z wierzchoka b do e 08 gr.EdgeD(b, e); 09 } // Wypisz graf 10 gr.Write(); 11 return 0; 12 }

Listing 2.4: Peny kod rdowy programu konwertuj cego reprezentacj grafu a 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include #include #include #include #include using namespace std; typedef vector VI; typedef long long LL; #dene FOR(x, b, e) for(int x=b; x=(e); x) #dene REP(x, n) for(int x=0; x> b >> e; gr.EdgeD(b, e); } gr.Write(); return 0; }

2.2. Przeszukiwanie grafu wszerzBFS czyli przeszukiwanie grafu wszerz (ang. breadth - rst Literatura search), jest metod systematycznego badania struktury grafu. Mea [WDA] - 23.2 toda ta zakada, e dany jest graf G = (V, E) (skierowany bd niea [ASD] - 1.5.3 skierowany), oraz wyrniony wierzchoek s, zwany rdem prze[KDP] - 2.3 szukiwania. Dla kadego wierzchoka v V , algorytm BFS oblicza odlego t(v) od wierzchoka s (rozumian jako najmniejsz a a liczb krawdzi na ciece od wierzchoka s do v). Wyznaczany jest rwnie wierzchoek s(v) poczony krawdzi z v, z ktrego prowadzi najkrtsza cieka ze rda wyszukiwaa a nia. Zasada dziaania algorytmu BFS jest prosta na pocztku, za odwiedzony wierzchoa ek uwaa si tylko s wyznaczona dla niego odlego to 0. Nastpnie przetwarzane s a wierzchoki v, dla ktrych odlego zostaa ju wyznaczona, w kolejnoci niemalejcych oda legoci dla kadego nie odwiedzonego ssiada u wierzchoka v, przypisywane s wartoci a a t(u) = t(v) + 1, s(u) = v. Na skutek wykonania algorytmu BFS, konstruowane jest drzewo przeszukiwa wszerz, w skad ktrego wchodz wszystkie wierzchoki osigalne ze rda wya a szukiwania, oraz krawdzie konstruujce najkrtsze cieki (reprezentowane przez zmienne a s(v)). Ze wzgldu na fakt, i nie wszystkie krawdzie grafu G musz znajdowa si w drzewie a przeszukiwa BFS, istnieje moliwo klasykacji krawdzi grafu G. Rozrniane s nasta pujce typy krawdzi, ktrych denicja ma sens w przypadku rozpatrywania konkretnego a drzewa przeszukiwa (denicje te s uywane nie tylko w ramach przeszukiwania wszerz): a Denicja 2.2.1 Krawd drzewowa, jest to krawd grafu G naleca do wyznaczonego lasu a przeszukiwa. Denicja 2.2.2 Krawd niedrzewowa, jest to krawd grafu G, ktra nie naley do wyznaczonego lasu przeszukiwa. 18

Denicja 2.2.3 Krawd powrotna, jest to krawd niedrzewowa, ktra prowadzi z wierzchoka v do jego przodka w lesie przeszukiwania. Denicja 2.2.4 Krawd w przd, jest to krawd niedrzewowa, ktra prowadzi z wierzchoka v do jego potomka w lesie przeszukiwania. Denicja 2.2.5 Krawd poprzeczna, jest to krawd niedrzewowa, ktra prowadzi z wierzchoka v do wierzchoka nie bdcego, ani jego poprzednikiem, ani nastpnikiem w wyznaczoa nym lesie przeszukiwa. W przypadku przeszukiwania wszerz grafw nieskierowanych nie zawierajcych multikraa wdzi, krawdzie w przd oraz krawdzie powrotne nie wystpuj, natomiast dla grafw skiea rowanych nie wystpuj krawdzie w przd. W zalenoci od rodzaju stosowanego przeszukia wania, krawdzie poszczeglnych klas mog mie ciekawe wasnoci, ktre s wykorzystywane a a w rnego rodzaju algorytmach. Najciekawsz wasnoci, w przypadku przeszukiwania grafu a a wszerz, jest fakt, i dla kadej krawdzi (u, v) E zachodzi d(u) = d(v) lub d(u) = d(v) 1. Dziki tej wasnoci, algorytm BFS moe by wykorzystywany do wyznaczania najkrtszych cieek midzy zadan par wierzchokw. a a Algorytm BFS zrealizowany zosta jako funkcja void Graph::Bfs(int), ktra przyjmuje jeden parametr numer wierzchoka bdcego rdem przeszukiwania. Implea mentacja wymaga wzbogacenia struktury wierzchokw o dwie dodatkowe zmienne int t oraz int s. Po wykonaniu algorytmu na grae, zmienna int t jest rwna odlegoci wierzchoka od rda wyszukiwania, natomiast zmienna int s zawiera numer wierzchoka, z ktrego proa wadzi znaleziona, najkrtsza cieka. Zmienne int s wyznaczaj tzw. las przeszukiwania grafu wszerz przykad takiego lasu przedstawiony jest na rysunku 2.2. Implementacja funkcji void Graph::Bfs(int) znajduje si na listingu 2.5.Listing 2.5: Implementacja funkcji void Graph::Bfs(int) // Po wykonaniu algorytmu BFS, pole int t wierzchoka zawiera odlego od // rda (-1 w przypadku, gdy wierzchoek jest nieosigalny ze rda), pole // int s zawiera numer ojca w drzewie BFS (dla wierzchoka bdcego rdem // wyszukiwania oraz wierzchokw nieosigalnych jest to -1) 01 void Bfs(int s) { // Dla kadego wierzchoka w grafie ustawiana jest pocztkowa warto zmiennych // t oraz s na -1. rdo wyszukiwania ma czas rwny 0 02 FOREACH(it, g) it->t = it->s = -1; 03 g[s].t = 0; // Algorytm BFS jest realizowany przy uyciu kolejki FIFO, do ktrej wstawiane // s kolejne wierzchoki oczekujce na przetworzenie 04 int qu[SIZE(g)], b, e; // Do kolejki wstawione zostaje rdo 05 qu[b = e = 0] = s; // Dopki w kolejce s jakie wierzchoki... 06 while (b v].t == -1) { 09 g[qu[++e] = it->v].t = g[s].t + 1;

19

0 1 3 5 2 1 2 1

-1 0

4

1

(a)

(b)

Rysunek 2.2: (a) nieskierowany graf o szeciu wierzchokach [0 . . . 5], (b) wyznaczone drzewo BFS dlagrafu z rysunku (a) i wierzchoka rdowego 2 (wewntrz wierzchokw znajduj si wya a znaczone czasy). Krawd (4, 5) jest jedyn krawdzi niedrzewow jest ona jednoczenie a a a krawdzi poprzeczn. a a

Listing 2.5: (c.d. listingu z poprzedniej strony) 10 g[it->v].s = s; 11 } 12 } 13 }

Dla grafu przedstawionego na rysunku 2.2.a, po wykonaniu funkcji Graph::Bfs(2), wartoci zmiennych wyliczone przez algorytm, przedstawione s na listingu 2.6, natomiast na a listingu 2.7 umieszczony jest kod rdowy programu uytego do wygenerowania tego wyniku. Algorytm przeszukiwania grafw metod BFS ma zoono czasow O(n + m). Wynika a a to z faktu, i kady wierzchoek w grae odwiedzany jest co najwyej raz, a podczas jego przetwarzania, wszystkie krawdzie z niego wychodzce s analizowane jednokrotnie. a aListing 2.6: Przykad uycia algorytmu BFS dla grafu z rysunku 2.2 i wierzchoka rdowego 2.

Wierzcholek Wierzcholek Wierzcholek Wierzcholek Wierzcholek Wierzcholek

0: 1: 2: 3: 4: 5:

czas czas czas czas czas czas

= = = = = =

-1, ojciec w drzewie BFS = -1 1, ojciec w drzewie BFS = 2 0, ojciec w drzewie BFS = -1 2, ojciec w drzewie BFS = 1 1, ojciec w drzewie BFS = 2 1, ojciec w drzewie BFS = 2

Listing 2.7: Kod rdowy programu uytego do wyznaczenia wyniku z listingu 2.6. Peny kod rdowy programu znajduje si w pliku bfs str.cpp // Krawdzie grafu nieskierowanego wymagaj dodatkowego pola int rev 01 struct Ve { 02 int rev; 03 }; // Wzbogacenie wierzchokw musi zawiera pola wymagane przez algorytm BFS 04 struct Vs { 05 int t, s; 06 };

20

Listing 2.7: (c.d. listingu z poprzedniej strony) 07 int main() { 08 int n, m, s, b, e; // Wczytaj liczb wierzchokw, krawdzi oraz numer wierzchoka startowego 09 cin >> n >> m >> s; 10 Graph g(n); // Dodaj do grafu wszystkie krawdzie 11 REP(x,m) { 12 cin >> b >> e; 13 g.EdgeU(b, e); 14 } // Wykonaj algorytm BFS 15 g.Bfs(s); // Wypisz wynik 16 REP(x, n) cout m >> s; // Skonstruuj odpowiedni graf 10 Graph g(n); // Dodaj do grafu wszystkie krawdzie

27

Listing 2.12: (c.d. listingu z poprzedniej strony) 11 REP(x,m) { 12 cin >> b >> e; 13 g.EdgeU(b, e); 14 } // Wykonaj algorytm DFS i wypisz wynik 15 g.Dfs(s); 16 REP(x, SIZE(g.g)) cout v] = nr); // Jeli wykonywana jest pierwsza faza, to wstaw wierzchoek do listy, jeli // natomiast druga, to zaktualizuj jego czas 09 if (phase) vis.PB(v); 10 else g[v].t = nr; 11 } // Funkcja wyznaczajca silnie spjne skadowe w grafie 12 Graph Scc() { // Graf gt to graf transponowany, natomiast res to konstruowany graf // silnie spjnych skadowych 13 Graph gt(SIZE(g)), res(SIZE(g)), *tab[] = { 14 this, &gt}; 15 gt.sccRes = &res; 16 gt.vis.resize(SIZE(g), -1); 17 vis.clear(); // Budowa grafu transpozycyjnego 18 REP(i, SIZE(g)) FOREACH(it, g[i]) gt.EdgeD(it->v, i); // Przeprowad dwie fazy algorytmu DFS... 19 REP(i, 2) { // Zaznacz wierzchoki jako nieodwiedzone 20 FOREACH(it, tab[i]->g) it->t = -1; 21 int comp = 0, v; // Dla kolejnych, nieodwiedzonych wierzchokw, wykonaj przeszukiwanie 22 FORD(j, SIZE(g) - 1, 0) 23 if (tab[i]->g[v = (i ? vis[j] : j)].t == -1) 24 tab[i]->SccDfs(v, comp++, 1 - i); 25 if (i) res.g.resize(comp); 26 } 27 REP(i, SIZE(g)) g[i].t = gt.g[i].t;

32

Listing 2.14: (c.d. listingu z poprzedniej strony) 28 return res; 29 }

Zoono czasowa obu przedstawionych funkcji void Graph::SccS() oraz Graph Graph::Scc() jest liniowa, ze wzgldu na wielko wejciowego grafu (O(n + m)). Wynika to z faktu, e obie funkcje wykonuj dwukrotnie zmodykowany algorytm DFS. a Funkcja void Graph::SccS() nie tylko jest krtsza w implementacji, ale w praktyce okazuje si by szybsza, ze wzgldu na brak koniecznoci konstruowania grafu wynikowego, dlatego te, jeli rezultat przez ni wyznaczany jest wystarczajcy, to nie naley korzysta z a a Graph Graph::Scc().Listing 2.15: Wynik wyznaczony przez funkcj Graph::Scc() dla grafu z rysunku 2.4.a

Wierzcholek 0 nalezy do silnie spojnej Wierzcholek 1 nalezy do silnie spojnej Wierzcholek 2 nalezy do silnie spojnej Wierzcholek 3 nalezy do silnie spojnej Wierzcholek 4 nalezy do silnie spojnej Wierzcholek 5 nalezy do silnie spojnej Wierzcholek 6 nalezy do silnie spojnej Wierzcholek 7 nalezy do silnie spojnej Graf silnie spojnych skladowych: 0: 2 3 4 1: 2 2: 3: 4 4:

skladowej skladowej skladowej skladowej skladowej skladowej skladowej skladowej

numer numer numer numer numer numer numer numer

0 0 2 2 2 1 3 4

Listing 2.16: Kod rdowy programu uytego do wyznaczenia wyniku z listingu 2.15. Peny kod rdowy programu znajduje si w pliku scc str.cpp 01 struct Ve {}; // Wzbogacenie dla wierzchokw zawiera pole, w ktrym umieszczany jest numer // silnie spjnej skadowej 02 struct Vs { 03 int t; 04 }; 05 int main() { 06 int n, m, s, b, e; 07 Ve ed; // Wczytaj liczb wierzchokw oraz krawdzi 08 cin >> n >> m; 09 Graph g(n); // Dodaj do grafu wszystkie krawdzie 10 REP(x, m) { 11 cin >> b >> e; 12 g.EdgeD(b, e);

33

Listing 2.16: (c.d. listingu z poprzedniej strony) 13 } // Wykonaj algorytm Scc oraz wypisz wyznaczony wynik 14 Graph scc = g.Scc(); 15 REP(x,n) cout > b >> e; 11 g.EdgeD(b, e); 12 } // Wyznacz porzdek topologiczny oraz wypisz wynik 13 VI res = g.TopoSortV(); 14 cout PB(MP(v