Zaawansowane algorytmy i struktury danych/Wykład 7: Różnice pomiędzy wersjami
Nie podano opisu zmian |
|||
Linia 1: | Linia 1: | ||
== Abstrakt == | == Abstrakt == | ||
W wykładzie tym skoncentrujemy się na problemie znajdowania najliczniejszych skojarzeń w grafach dwudzielnych. Zaczniemy od przedstawienia idei ścieżek powiększających, a następie użyjemy jej do konstrukcji algorytmu znajdującego maksymalne skojarzenie w grafie <math>G=(V,E)</math> w czasie <math>O(|V||E|)</math>. Następnie przedstawimy algorytm Hopcrofta-Karpa, który działać będzie w | W wykładzie tym skoncentrujemy się na problemie znajdowania najliczniejszych skojarzeń w grafach dwudzielnych. Zaczniemy od przedstawienia idei ścieżek powiększających, a następie użyjemy jej do konstrukcji algorytmu znajdującego maksymalne skojarzenie w grafie <math>G=(V,E)</math> w czasie <math>O(|V||E|)</math>. Następnie przedstawimy algorytm Hopcrofta-Karpa, który działać będzie w czasie <math>O(\sqrt{|V|}|E|)</math>. | ||
== Problem maksymalnego skojarzenia w grafie dwudzielnym == | == Problem maksymalnego skojarzenia w grafie dwudzielnym == | ||
Niech <math>G=(V,E)</math> będzie grafem nieskierowanym. {{kotwica|skojarzenie|'''Skojarzeniem'''}} w grafie <math>G</math> nazywamy każdy podzbiór krawędzi <math>M\subseteq E</math> taki, w którym co najwyżej jedna krawędź z <math>M</math> jest incydentna z każdym wierzchołkiem w <math>V</math>. O wierzchołku <math>v</math> incydentnym do pewniej krawędzi z <math>M</math> mówimy, że jest '''skojarzony''', w przeciwnym przypadku <math>v</math> nazywamy '''wolnym'''. Podobnie jeżeli krawędź <math>e</math> należy do skojarzenia to mówimy, że jest ona '''skojarzona''' a w przeciwnym wypadku mówimy, że jest to krawędź '''wolna'''. Skojarzenie <math>M</math> nazywamy {{kotwica|maksymalne_skojarzenie|'''maksymalnym'''}} gdy ma ono największą liczność spośród skojarzeń w <math>G</math>. W trakcie tego wykładu zajmiemy się tylko problemem znajdowania skojarzeń w {{kotwica|graf_dwudzielny|'''grafach dwudzielnych'''}} czyli takich w których zbiór wierzchołków można podzielić na <math>V = V_1\cup V_2</math> gdzie <math>V_1</math> i <math>V_2</math> są rozłączne, a wszystkie krawędzie z <math>E</math> prowadzą pomiędzy <math> | Niech <math>G=(V,E)</math> będzie grafem nieskierowanym. {{kotwica|skojarzenie|'''Skojarzeniem'''}} w grafie <math>G</math> nazywamy każdy podzbiór krawędzi <math>M\subseteq E</math> taki, w którym co najwyżej jedna krawędź z <math>M</math> jest incydentna z każdym wierzchołkiem w <math>V</math>. O wierzchołku <math>v</math> incydentnym do pewniej krawędzi z <math>M</math> mówimy, że jest '''skojarzony''', w przeciwnym przypadku <math>v</math> nazywamy '''wolnym'''. Podobnie jeżeli krawędź <math>e</math> należy do skojarzenia to mówimy, że jest ona '''skojarzona''' a w przeciwnym wypadku mówimy, że jest to krawędź '''wolna'''. Skojarzenie <math>M</math> nazywamy {{kotwica|maksymalne_skojarzenie|'''maksymalnym'''}} gdy ma ono największą liczność spośród skojarzeń w <math>G</math>. W trakcie tego wykładu zajmiemy się tylko problemem znajdowania skojarzeń w {{kotwica|graf_dwudzielny|'''grafach dwudzielnych'''}} czyli takich w których zbiór wierzchołków można podzielić na <math>V = V_1\cup V_2</math> gdzie <math>V_1</math> i <math>V_2</math> są rozłączne, a wszystkie krawędzie z <math>E</math> prowadzą pomiędzy <math>V_1</math> i <math>V_2</math>. | ||
== Ścieżki powiększające == | == Ścieżki powiększające == | ||
{{kotwica|ścieżka_powiększająca|'''Ścieżką powiększającą'''}} nazwiemy ścieżkę prostą <math>p</math> taką, że jej krawędzie są na przemian skojarzone i wolne, a końce są wolne. Łatwo zauważyć, że jeżeli istnieje ścieżka powiększająca <math>p</math> względem <math>M</math> to <math>M</math> nie jest skojarzeniem maksymalnym. Używając wtedy ścieżki <math>p</math> możemy skonstruować skojarzenie większe biorąc <math>M = M \oplus | {{kotwica|ścieżka_powiększająca|'''Ścieżką powiększającą'''}} nazwiemy ścieżkę prostą <math>p</math> taką, że jej krawędzie są na przemian skojarzone i wolne, a końce są wolne. Łatwo zauważyć, że jeżeli istnieje ścieżka powiększająca <math>p</math> względem <math>M</math> to <math>M</math> nie jest skojarzeniem maksymalnym. Używając wtedy ścieżki <math>p</math> możemy skonstruować skojarzenie większe biorąc <math>M = M \oplus p</math>, czyli zamieniając na ścieżce krawędzie wolne na skojarzone i na odwrót. Możemy pokazać także przeciwne wynikanie: | ||
{{twierdzenie|1 [Twierdzenie Berge'a]|twierdzenie_1|3= Skojarzenie <math>M</math> jest maksymalne gdy nie istnieje względem niego żadna ścieżka powiększająca. }} | {{twierdzenie|1 [Twierdzenie Berge'a]|twierdzenie_1|3= Skojarzenie <math>M</math> jest maksymalne, gdy nie istnieje względem niego żadna ścieżka powiększająca. }} | ||
{{dowod|||3= Załóżmy przeciwnie, że istnieje skojarzenie <math>M'</math> liczniejsze niż <math>M</math>. Rozważmy graf <math>G' = (V, M \oplus M')</math>. Zauważmy, że w <math>G'</math> każdy wierzchołek ma stopień co najwyżej <math>2</math>, w związku z tym <math>G'</math> składa się z rozłącznych ścieżek i cykli. Na każdym cyklu występuje tyle samo krawędzi z <math>M</math> co <math>M'</math>. Natomiast | {{dowod|||3= Załóżmy przeciwnie, że istnieje skojarzenie <math>M'</math> liczniejsze niż <math>M</math>. Rozważmy graf <math>G' = (V, M \oplus M')</math>. Zauważmy, że w <math>G'</math> każdy wierzchołek ma stopień co najwyżej <math>2</math>, w związku z tym <math>G'</math> składa się z rozłącznych ścieżek i cykli. Na każdym cyklu występuje tyle samo krawędzi z <math>M</math> co <math>M'</math>. Natomiast w ścieżkach może występować co najwyżej o jedną krawędź więcej z któregoś skojarzenia. W grafie <math>G'</math> jest więcej krawędzi z <math>M'</math> niż z <math>M</math>, a zatem musi też istnieć ścieżka na której jest więcej krawędzi z <math>M'</math>. Musi to być oczywiście ścieżka powiększająca. }} | ||
=== Algorytm wykorzystujący ścieżki powiększające === | === Algorytm wykorzystujący ścieżki powiększające === | ||
Zastanówmy się teraz jak efektywnie sprawdzić, czy w grafie dwudzielnym nie ma ścieżki powiększającej, bądź jeżeli jest to ją znaleźć. Dla grafu dwudzielnego <math>G=(V_1 \cup V_2, E)</math> oraz skojarzenia <math>M</math> zdefiniujmy skierowany graf <math>G_{M}= ( | Zastanówmy się teraz jak efektywnie sprawdzić, czy w grafie dwudzielnym nie ma ścieżki powiększającej, bądź jeżeli jest to ją znaleźć. Dla grafu dwudzielnego <math>G=(V_1 \cup V_2, E)</math> oraz skojarzenia <math>M</math> zdefiniujmy skierowany graf <math>G_{M}= (V_1\cup V_2, {E}_M)</math> jako | ||
{{wzor2|1= | {{wzor2|1= | ||
<math> | <math> | ||
{E} = \{(v_1, v_2): v_1v_2 \in E, v_1 \in V_1, v_2 \in V_2\} \cup \{(v_2, v_1): | \begin{array}{r@{}c@{}l} | ||
{E}_M &=& \{(v_1, v_2): v_1v_2 \in E, v_1 \in V_1, v_2 \in V_2\}\\ | |||
&\cup& \{(v_2, v_1): v_1v_2 \in M, v_1 \in V_1, v_2 \in V_2\}. | |||
\end{array} | |||
</math> | </math> | ||
}} | }} | ||
Linia 29: | Linia 32: | ||
{{algorytm|znajdowania ścieżki powiększającej|algorytm_ścieżka_powiększająca|3= | {{algorytm|znajdowania ścieżki powiększającej|algorytm_ścieżka_powiększająca|3= | ||
ZNAJDŹ-ŚCIEŻKĘ-POWIĘKSZAJĄCĄ(G = (V_1 \cup V_2,E),M) | ZNAJDŹ-ŚCIEŻKĘ-POWIĘKSZAJĄCĄ<math>(G = (V_1 \cup V_2,E),M)</math> | ||
1 <math>V_1' = </math> zbiór wierzchołków wolnych w <math>V_1</math> | 1 <math>V_1' = </math> zbiór wierzchołków wolnych w <math>V_1</math> | ||
2 <math>V_2' = </math> zbiór wierzchołków wolnych w <math>V_2</math> | 2 <math>V_2' = </math> zbiór wierzchołków wolnych w <math>V_2</math> | ||
Linia 35: | Linia 38: | ||
5 znajdź ścieżkę <math>p</math> z <math>V_1'</math> do <math>V_2'</math> w <math>{G}_M</math> | 5 znajdź ścieżkę <math>p</math> z <math>V_1'</math> do <math>V_2'</math> w <math>{G}_M</math> | ||
6 '''if''' <math>p</math> nie istnieje '''then''' | 6 '''if''' <math>p</math> nie istnieje '''then''' | ||
7 '''return''' NIL ''(nie ma ścieżki powiększającej)'' | 7 '''return''' <math>NIL</math> ''(nie ma ścieżki powiększającej)'' | ||
8 '''return''' <math>p</math> ''(<math>p</math> to ścieżka powiększająca w <math>G</math>)'' | 8 usuń cykle z <math>p</math> tak aby <math>p</math> była ścieżką prostą | ||
9 '''return''' <math>p</math> ''(<math>p</math> to ścieżka powiększająca w <math>G</math>)'' | |||
}} | }} | ||
{{lemat|2|lemat_2|3= Powyższy algorytm znajduje ścieżkę <math>p</math> | {{lemat|2|lemat_2|3= Powyższy algorytm znajduje ścieżkę <math>p</math> wtedy i tylko wtedy gdy w <math>G</math> istnieje ścieżka powiększająca względem <math>M</math>. Co więcej znaleziona ścieżka jest ścieżką powiększającą.}} | ||
{{dowod|||3= Załóżmy, że ścieżka <math>p</math> istnieje | {{dowod|||3= Załóżmy, że ścieżka <math>p</math> istnieje. Z konstrukcj algorytmu wiemy, że jest to ścieżka, która | ||
# zaczyna się w wierzchołku wolnym, | # zaczyna się w wierzchołku wolnym, | ||
# z <math>V_1</math> do <math>V_2</math> idzie krawędzią wolną, | # z <math>V_1</math> do <math>V_2</math> idzie krawędzią wolną, | ||
Linia 47: | Linia 51: | ||
# kończy się w <math>V_2</math> krawędzią wolną. | # kończy się w <math>V_2</math> krawędzią wolną. | ||
Ścieżka <math>p</math> spełnia wszystkie warunki dla [[#scieżka_powiększająca|ścieżki powiększającej]] oprócz bycia ścieżką prostą. Jeżeli <math>p</math> przechodzi dwa razy przez ten sam wierzchołek <math>v \in V_1</math>, to wchodzi do niego dwa razy krawędzią skojarzoną, a wychodzi krawędzią nieskojarzoną. Jeżeli teraz usuniemy kawałek ścieżki pomiędzy tymi dwoma wejściami do <math>v</math> to powyższe cztery warunki nadal będą zachodzić. Możemy więc zachowując je zamienić ścieżkę <math>p</math> na ścieżkę prostą. | Ścieżka <math>p</math> spełnia wszystkie warunki dla [[#scieżka_powiększająca|ścieżki powiększającej]] oprócz bycia ścieżką prostą. Jeżeli <math>p</math> przechodzi dwa razy przez ten sam wierzchołek <math>v \in V_1</math>, to wchodzi do niego dwa razy krawędzią skojarzoną, a wychodzi krawędzią nieskojarzoną. Jeżeli teraz usuniemy kawałek ścieżki pomiędzy tymi dwoma wejściami do <math>v</math> (linia 8) to powyższe cztery warunki nadal będą zachodzić. Możemy więc zachowując je zamienić ścieżkę <math>p</math> na ścieżkę prostą. | ||
Natomiast jeżeli w grafie <math>G</math> jest ścieżka powiększająca względem <math>M</math> to możemy ją wprost przetłumaczyć na ścieżkę w | Natomiast jeżeli w grafie <math>G</math> jest ścieżka powiększająca względem <math>M</math> to możemy ją wprost przetłumaczyć na ścieżkę w gafie <math>{G}_M</math>.}} | ||
Jesteśmy już gotowi | Jesteśmy już gotowi aby skonstruować pierwszy algorytmu znajdujący maksymalne skojarzenie w grafie dwudzielnym. | ||
{{algorytm|znajdujący maksymalne skojarzenie w grafie dwudzielnym|algorytm_skojarzenia_1|3= | {{algorytm|znajdujący maksymalne skojarzenie w grafie dwudzielnym|algorytm_skojarzenia_1|3= | ||
Linia 75: | Linia 79: | ||
Algorytm Hopcrofta-Karpa także wykorzystuje technikę ścieżek powiększających. Jednak w celu przyśpieszenia działania tej metody, zamiast wyszukiwać ścieżki pojedynczo, będziemy szukać wielu ścieżek na raz. Będziemy to robić jednak w taki sposób aby długości tych ścieżek systematycznie rosły, będziemy mogli skorzystać wtedy z następującego lematu, który mówi, że długich ścieżek jest. | Algorytm Hopcrofta-Karpa także wykorzystuje technikę ścieżek powiększających. Jednak w celu przyśpieszenia działania tej metody, zamiast wyszukiwać ścieżki pojedynczo, będziemy szukać wielu ścieżek na raz. Będziemy to robić jednak w taki sposób aby długości tych ścieżek systematycznie rosły, będziemy mogli skorzystać wtedy z następującego lematu, który mówi, że długich ścieżek jest mało. | ||
{{lemat|3|lemat_3|3= | {{lemat|3|lemat_3|3= | ||
Linia 87: | Linia 91: | ||
=== Maksymalny zbiór rozłącznych wierzchołkowy ścieżek powiększających === | === Maksymalny zbiór rozłącznych wierzchołkowy ścieżek powiększających === | ||
{{kotwica|max_ścieżki|}} | {{kotwica|max_ścieżki|}} | ||
W celu zagwarantowania wzrostu długości ścieżek po każdej fazie będziemy | W celu zagwarantowania wzrostu długości ścieżek po każdej fazie będziemy w każdej fazie konstruuować maksymalny zbiór rozłącznych wierzchołkowo najkrótszych ścieżek powiększających <math>P</math>. Pokażemy teraz, że po powiększeniu skojarzenia przy pomocy wszystkich tych ścieżek długość najkrótszej ścieżki rośnie. Oznaczmy przez <math>M \oplus P = M \oplus \bigoplus_{p\in P} p</math>. | ||
{{lemat|4|lemat_4|3= | {{lemat|4|lemat_4|3= | ||
Linia 94: | Linia 98: | ||
{{dowod|||3= | {{dowod|||3= | ||
Weźmy najkrótszą ścieżkę powiększająca <math>\pi'</math> względem <math>M\oplus P</math>. Ścieżka ta musi przecinać się ze pewną ścieżką <math>\ | Weźmy najkrótszą ścieżkę powiększająca <math>\pi'</math> względem <math>M\oplus P</math>. Ścieżka ta musi przecinać się ze pewną ścieżką <math>\pi_1</math> ze zbioru <math>P</math> inaczej mówilibyśmy powiększyć <math>P</math> o <math>\pi_1</math>. Pokażemy teraz, że <math>|\pi'| \ge |\pi_1| +1</math>. Kolejne fazy tego dowodu zobrazowane są na animacji poniżej | ||
<flash>file=Zasd_ilustr_o.swf |width=600|height=500</flash>. | <flash>file=Zasd_ilustr_o.swf |width=600|height=500</flash>. | ||
Musimy jednak pamiętać, że ścieżka <math>\pi'</math> może przecinać więcej niż jedną ścieżkę z <math>P</math>. Bez straty ogólności możemy założyć, że <math>p_1</math> jest pierwszą przecinaną ścieżką, a <math>p_2</math> ostatnią. Niech <math>u_i</math> będzie pierwszym wierzchołkem wspólnym dla ścieżek <math>\pi_i</math> i <math>\pi'</math>. Natomiast niech <math>v_1</math> będzie początkiem ścieżki <math>\pi</math>, a <math>v_2</math> jej końcem. Podobnie niech <math>v_1'</math> i <math>v_2'</math> będą początkiem i końcem ścieżki <math>\pi'</math>. Ze ścieżek <math>\pi</math>, <math>\pi_1</math> oraz <math>\pi_2</math> możemy skonstruować dwie nowe ścieżki <math>R_1</math> i <math>R_2</math>. Niech <math>R_i</math> idzie kawałkiem ścieżki <math>\pi_i</math> z <math>v_i</math> do <math>u_i</math>, a następnie kawałkiem ścieżki <math>\pi'</math> z <math>u_i</math> do <math>v_i'</math>. Sumaryczna długość ścieżek <math>R_1</math> i <math>R_2</math> jest mniejsza o co najmniej <math>1</math> od długości ścieżek <math>\pi</math> i <math>\pi'</math>, możemy wiec zapisać: | |||
Wersja z 13:53, 19 wrz 2006
Abstrakt
W wykładzie tym skoncentrujemy się na problemie znajdowania najliczniejszych skojarzeń w grafach dwudzielnych. Zaczniemy od przedstawienia idei ścieżek powiększających, a następie użyjemy jej do konstrukcji algorytmu znajdującego maksymalne skojarzenie w grafie w czasie . Następnie przedstawimy algorytm Hopcrofta-Karpa, który działać będzie w czasie .
Problem maksymalnego skojarzenia w grafie dwudzielnym
Niech będzie grafem nieskierowanym. Skojarzeniem w grafie nazywamy każdy podzbiór krawędzi taki, w którym co najwyżej jedna krawędź z jest incydentna z każdym wierzchołkiem w . O wierzchołku incydentnym do pewniej krawędzi z mówimy, że jest skojarzony, w przeciwnym przypadku nazywamy wolnym. Podobnie jeżeli krawędź należy do skojarzenia to mówimy, że jest ona skojarzona a w przeciwnym wypadku mówimy, że jest to krawędź wolna. Skojarzenie nazywamy maksymalnym gdy ma ono największą liczność spośród skojarzeń w . W trakcie tego wykładu zajmiemy się tylko problemem znajdowania skojarzeń w grafach dwudzielnych czyli takich w których zbiór wierzchołków można podzielić na gdzie i są rozłączne, a wszystkie krawędzie z prowadzą pomiędzy i .
Ścieżki powiększające
Ścieżką powiększającą nazwiemy ścieżkę prostą taką, że jej krawędzie są na przemian skojarzone i wolne, a końce są wolne. Łatwo zauważyć, że jeżeli istnieje ścieżka powiększająca względem to nie jest skojarzeniem maksymalnym. Używając wtedy ścieżki możemy skonstruować skojarzenie większe biorąc , czyli zamieniając na ścieżce krawędzie wolne na skojarzone i na odwrót. Możemy pokazać także przeciwne wynikanie:
Twierdzenie 1 [Twierdzenie Berge'a]
Dowód

Algorytm wykorzystujący ścieżki powiększające
Zastanówmy się teraz jak efektywnie sprawdzić, czy w grafie dwudzielnym nie ma ścieżki powiększającej, bądź jeżeli jest to ją znaleźć. Dla grafu dwudzielnego oraz skojarzenia zdefiniujmy skierowany graf jako
Algorytm znajdowania ścieżki powiększającej
ZNAJDŹ-ŚCIEŻKĘ-POWIĘKSZAJĄCĄ 1 zbiór wierzchołków wolnych w 2 zbiór wierzchołków wolnych w 3 skonstruuj graf skierowany 5 znajdź ścieżkę z do w 6 if nie istnieje then 7 return (nie ma ścieżki powiększającej) 8 usuń cykle z tak aby była ścieżką prostą 9 return ( to ścieżka powiększająca w )
Lemat 2
Dowód
- zaczyna się w wierzchołku wolnym,
- z do idzie krawędzią wolną,
- z do wraca krawędzią skojarzoną,
- kończy się w krawędzią wolną.
Ścieżka spełnia wszystkie warunki dla ścieżki powiększającej oprócz bycia ścieżką prostą. Jeżeli przechodzi dwa razy przez ten sam wierzchołek , to wchodzi do niego dwa razy krawędzią skojarzoną, a wychodzi krawędzią nieskojarzoną. Jeżeli teraz usuniemy kawałek ścieżki pomiędzy tymi dwoma wejściami do (linia 8) to powyższe cztery warunki nadal będą zachodzić. Możemy więc zachowując je zamienić ścieżkę na ścieżkę prostą.
Natomiast jeżeli w grafie jest ścieżka powiększająca względem to możemy ją wprost przetłumaczyć na ścieżkę w gafie .
Jesteśmy już gotowi aby skonstruować pierwszy algorytmu znajdujący maksymalne skojarzenie w grafie dwudzielnym.
Algorytm znajdujący maksymalne skojarzenie w grafie dwudzielnym
MAKSYMALNE-SKOJARZENIE(G = (V_1 \cup V_2,E)) 1 1 repeat 2 ZNAJDŹ-ŚCIEŻKĘ-POWIĘKSZAJĄCĄ 3 if then 4 6 until 5 return
Wyszukiwanie ścieżki powiększającej zobrazowane jest na poniższej animacji.
<flash>file=Zasd_Ilustr_d.swf |width=600|height=300</flash>
Poprawność tego algorytmu wynika z Lematu 2 oraz Twierdzenia Berge'a. Ponieważ jest ograniczeniem górnym na rozmiar maksymalnego skojarzenia, a w każdym kroku pętli rozmiar skojarzenia rośnie o , to pętla ta zostanie wykonana co najwyżej razy. Wyszukanie jednej ścieżki powiększającej zajmuje czas , a więc całkowity czas działania algorytmu to .
Algorytm Hopcrofta-Karpa
Algorytm Hopcrofta-Karpa także wykorzystuje technikę ścieżek powiększających. Jednak w celu przyśpieszenia działania tej metody, zamiast wyszukiwać ścieżki pojedynczo, będziemy szukać wielu ścieżek na raz. Będziemy to robić jednak w taki sposób aby długości tych ścieżek systematycznie rosły, będziemy mogli skorzystać wtedy z następującego lematu, który mówi, że długich ścieżek jest mało.
Lemat 3
Dowód

Maksymalny zbiór rozłącznych wierzchołkowy ścieżek powiększających
W celu zagwarantowania wzrostu długości ścieżek po każdej fazie będziemy w każdej fazie konstruuować maksymalny zbiór rozłącznych wierzchołkowo najkrótszych ścieżek powiększających . Pokażemy teraz, że po powiększeniu skojarzenia przy pomocy wszystkich tych ścieżek długość najkrótszej ścieżki rośnie. Oznaczmy przez .
Lemat 4
Dowód

Zajmijmy się teraz algorytmem konstrukcji zbioru ścieżek . W konstrukcji tej użyjemy trochę zmodyfikowanej procedury DFS.
Algorytm częściowego DFS
CZĘŚCIOWE-DFS 1 uruchom DFS(G,v) aż do momentu znalezienia pierwszego wierzchołka ze zbioru 2 usuń wszystkie odwiedzone wierzchołki w procedurze DFS z grafu 2 if istnieje ścieżka z do then 4 return p 5 else 6 return NIL
Procedura ta różni się od standardowej procedury DFS dwoma rzeczami. Po pierwsze prowadzi wyszukiwanie tylko do momentu znalezienia wierzchołka z . Po drugie po zakończonym wyszukiwaniu usuwa wszystkie odwiedzone wierzchołki, tak aby każda następna znaleziona ścieżka przez nie nie przechodziła. Procedurę tą wykorzystamy do grafu warstwowego skonstruowanego z grafu . Niech oznacza zbiór wierzchołków wolnych w . Oznaczmy przez odległość wierzchołka od wierzchołków z . Graf ma następujący zbiór krawędzi:
Lemat 5
Dowód

Lemat ten pozwala nam na konstrukcję następującego algorytmu wyszukującego maksymalny zbiór wierzchołkowo rozłącznych najkrótszych ścieżek powiększających.
Algorytm znajdujący maksymalny zbiór wierzchołkowo rozłącznych najkrótszych ścieżek powiększających
MAKSYMALNY-ZBIÓR-NAJKRÓTSZYCH-ŚCIEŻEK(G = (V_1 \cup V_2,E),M) 1 2 skonstruuj graf 3 niech będzie zbiorem wierzchołków wolnych w 4 for do 5 begin 6 CZĘŚCIOWE-DFS 7 if then 8 9 end 10 return
Lemat 6
Dowód

Algorytm
Zapiszmy teraz algorytm Hopcrofta-Karpa.
Algorytm Hopcrofta-Karpa
HOPCROFT-KARP(G = (V_1 \cup V_2)) 1 2 repeat 3 MAKSYMALNY-ZBIÓR-NAJKRÓTSZYCH-ŚCIEŻEK 4 if then 5 6 until 7 return M
<flash>file=Zasd_Ilustr_h.swf |width=600|height=300</flash>
Twierdzenie 7
Dowód
