Dany jest graf skierowany o n wierzchołkach. Napisz algorytm, który znajdzie najmniejszą liczbę krawędzi, które trzeba zamienić, aby można było dojść od punktu początkowego do końcowego.
Dany jest przykładowo następujący graf skierowany o 5 wierzchołkach. Szukamy drogi od A do E tak, aby trzeba było odwrócić jak najmniej krawędzi.
Najkrótsz ścieżka ma długość 2 i prowadzi A-D-E. Pokonanie takiej drogi wymaga odwrócenia dwóch krawędzi. Jednak jeśli wybierzemy trasę A-B-C-E to odwrócona zostanie tylko jedna krawędź. To jest ścieżka, którą należy wybrać, ponieważ chcemy ścieżkę na której trzeba dokonać jak najmniej odwróceń (idealnie jeśli nie trzeba wogle).
Zadanie można rozwiązać przy pomocy algorytmu BFS. Rozpoczynamy poszukiwania od węzła początkowego, a następnie dołączamy jego sąsiadów pod warunkiem, że ścieżka prowadząca do nich jeszcze nie istnieje lub liczba zamian nowej ścieżki jest mniejsza niż dotychczas znaleziona. W przypadku, gdy liczba zamian jest taka sama to należy wybrać krótszą ścieżkę.
Przykładowa dla podanego wyżej grafu rozpoczynamy poszukiwania od wierzchołka A. Dla każdego wierzchołka została podana jego aktualna odległość oraz ile trzeba było dokonać zamian.
Kolejka | A | B | C | D | E |
---|---|---|---|---|---|
A | - | 0 | ∞ | - | ∞ | - | ∞ | - | ∞ | - |
B, D | - | 0 | 1 | 0 | ∞ | - | 1 | 1 | ∞ | - |
D, C | - | 0 | 1 | 0 | ∞ | - | 1 | 1 | 2 | 2 |
C, E | - | 0 | 1 | 0 | 2 | 1 | 1 | 1 | ∞ | - |
E | - | 0 | 1 | 0 | 2 | 1 | 1 | 1 | 3 | 1 |
Algorytm skończył działanie, ponieważ kolejka jest pusta. Zwracana jest para wartości zgromadzona dla wierzchołka E. W tym przypadku odległość wynosi 3 i potrzeba zrobić dokładnie jedną zamianę.
Poniższa funkcja IleZamianPowrot() zwraca informację dla podanej macierzy długość ścieżki od start do koniec oraz informację ile krawędzi trzeba odwrócić.
Na początku algorytm inicjalizuje pustą tablicę dla każdego wierzchołka. Wierzchołkowi początkowemu i końcowemu nadawane są wartości początkowe. Następnie na kolejkę wrzucany jest wierzchołek początkowy i rozpoczyna się przeszukiwanie grafu i jego odpowiednia aktualizacja.
W celu przetestowania kodu można skorzystać z poniższej funkcji, która wczyta potrzebne dane:
Podany graf należy wpisać jako następującą macierz: