Informatyczny kącik olimpijski
Darmowe rozmowy
W tym miesiącu rozwiążemy zadanie Darmowe rozmowy z Obozu Naukowo-Treningowego im. Antoniego Kreczmara w roku 2011.
Zadanie. Firma telekomunikacyjna, chcąc poinformować swoich klientów o nowej promocji, zleciła jednemu ze swoich pracowników, aby osobiście zadzwonił on do niektórych klientów. Klientów jest a ponadto każdy z nich może zadzwonić do jednej ustalonej osoby za darmo. Pracownik wychodzi z założenia, że promocja jest tak świetna, że każdy klient, który się o niej dowie, będzie chciał się podzielić tą wiedzą z kimś innym, ale że ludzie są z natury oszczędni, poinformuje on tylko tę osobę, do której może zadzwonić bezpłatnie. Pracownik ma czas wykonać telefonów do klientów. Należy wyznaczyć, do których powinien zadzwonić, aby zmaksymalizować liczbę osób, które dowiedzą się o promocji.
Zbiór klientów możemy przedstawić jako graf skierowany o wierzchołkach, w którym istnieje krawędź od wierzchołka do wierzchołka jeśli klient może za darmo zadzwonić do klienta (Rys. 1). Zatem zadzwonienie do klienta spowoduje, że klienci odpowiadający wszystkim wierzchołkom osiągalnym z wierzchołka dowiedzą się o promocji.
Graf skierowany, w którym z każdego wierzchołka wychodzi dokładnie jedna krawędź, ma dość specyficzną strukturę: każda jego spójna składowa jest cyklem z podoczepianymi drzewami. W przypadku naszego zadania możemy tę strukturę jeszcze uprościć, konstruując skierowane drzewo o tej własności, że z optymalnego rozwiązania dla drzewa łatwo odtworzymy optymalne rozwiązanie dla pierwotnego grafu. Mianowicie każdą składową zastępujemy pojedynczą ścieżką o tej samej długości co cykl w tej składowej, a do końca tej ścieżki podczepiamy wszystkie drzewa ze składowej. Na końcu zaś wszystkie ścieżki podczepiamy do nowego wierzchołka 0 (Rys. 2). Pokazanie odpowiedniości między rozwiązaniami dla drzewa i pierwotnego grafu pozostawimy jako nietrudne ćwiczenie dla Czytelników.
W tym momencie nasze zadanie jest następujące: chcemy wybrać wierzchołków w skierowanym drzewie tak, aby liczba wierzchołków z nich osiągalnych była jak największa. Na początek poczyńmy dwie oczywiste obserwacje: wybierając wierzchołki, wystarczy ograniczyć się do liści w drzewie (w szczególności bez straty ogólności możemy założyć, że jest nie większe niż liczba liści). Ponadto w przypadku należy wybrać ten z liści, który leży w najdalszej odległości od korzenia drzewa. Okazuje się, że również dalej działa podejście zachłanne: kolejne liście opłaca się wybierać tak, aby leżały jak najdalej od zbioru wierzchołków już zaznaczonych (Rys. 3).
Pomysł ten możemy zaimplementować następująco: wykonujemy faz algorytmu. Zakładamy, że na początku -tej fazy mamy zaznaczony w drzewie zbiór wierzchołków osiągalnych z liści wybranych w poprzednich fazach. W fazie obliczamy odległości pozostałych wierzchołków do zbioru wybieramy liść o największej odległości i zaznaczamy wszystkie wierzchołki z niego osiągalne. Pojedynczą fazę wykonujemy w czasie zatem cały algorytm działa w czasie
Rozwiązanie to można przyspieszyć. Wierzchołki dodawane w kolejnych fazach tworzą ścieżki. Każda krawędź takiej ścieżki wchodząca do danego wierzchołka wychodzi z jednego z tych jego synów, których poddrzewa mają największą głębokość. Możemy zatem obliczyć wszystkie te ścieżki w czasie przeglądając drzewo od liści w górę, dla każdego wierzchołka pamiętając głębokość jego poddrzewa. Następnie wybieramy najdłuższych ścieżek, sortując ich długości przez zliczanie.
A jak udowodnić poprawność rozwiązania zachłannego? Niech będzie zbiorem wierzchołków, które leżą w odległości od najbliższego liścia. W szczególności jest zbiorem liści i z tego zbioru chcemy zaznaczyć pewne wierzchołków. Poruszając się w górę drzewa z tych wierzchołków, zaznaczymy ich rodziców, którzy znajdują się w zbiorze przy czym opłaca nam się tak wybrać liście, aby zbiór tych rodziców był jak największy. Oczywiście, będzie on miał rozmiar co najwyżej W ogólności, ze zbioru zaznaczymy co najwyżej wierzchołków. Załóżmy, że zbiór jest optymalnym rozwiązaniem dla to znaczy, że dla każdego w zbiorze zaznaczamy dokładnie wierzchołków. Jeśli liść wybrany w -tej fazie algorytmu leży w odległości to znaczy, że z każdego ze zbiorów zaznaczymy po jednym wierzchołku, natomiast wszystkie wierzchołki w zbiorach są już zaznaczone (więc ich rozmiary są nie większe niż ). Wynika z tego, że zbiór jest też optymalny, bo dla każdego w zbiorze zaznaczymy wierzchołków.
Co ciekawe, powyższy dowód daje nam prostsze rozwiązanie w przypadku, gdy interesuje nas tylko maksymalna liczba klientów, którzy dowiedzą się o promocji. Wystarczy bowiem w czasie wyznaczyć rozmiary zbiorów