Documente Academic
Documente Profesional
Documente Cultură
Contents
1 Discutarea problemelor de la OLI
2 Cicluri euleriene
2.1 Condiții de existență
2.1.1 Demonstrație pentru prima proprietate
2.2 Algoritmul lui Fleury
2.3 Algoritmul lui Hierholzer
2.4 Detalii de implementare
2.4.1 Stivă proprie
2.4.2 Graf neorientat
2.4.3 Punctul de pornire
2.5 Problema poștașului chinez
2.6 Probleme
3 Temă
Cicluri euleriene
Definiție: Fie un graf G = (V, E). Un ciclu în acest graf se numește ciclu eulerian dacă vizitează fiecare muchie
exact o dată.
Mai prezintă interes și cazul când un graf nu admite un ciclu eulerian, dar admite o cale euleriană, așadar o cale
care pornește dintr-un nod, se termină într-un alt nod și vizitează fiecare muchie exact o dată.
Condiții de existență
Un graf neorientat admite un ciclu eulerian dacă și numai dacă toate nodurile au grad par.
Un graf neorientat admite o cale euleriană dacă și numai dacă există exact două noduri cu grad impar.
Un graf orientat admite un ciclu eulerian dacă și numai dacă toate nodurile au gradul la intrare egal cu gradul
la ieșire.
Un graf orientat admite o cale euleriană dacă și numai dacă există exact un nod s cu ,
exact un nod t cu , iar pentru restul nodurilor .
algopedia.ro/wiki/index.php/Clasele_11-12_lecția_20_-_25_feb_2015 1/4
1/30/2021 Clasele 11-12 lecția 20 - 25 feb 2015 - Algopedia
Fie C ciclul găsit. Să considerăm gravul . În G′, toate nodurile continuă să aibă grade pare,
deoarece C scade o valoare pară din fiecare grad. Identificăm în mod recurent cicluri euleriene pentru
componentele conexe ale lui G′. Cazul de bază este graful fără muchii. Deoarece G este conex, C trebuie să aibă cel
puțin un nod în comun cu fiecare din componentele conexe ale lui G′. Inserăm ciclurile euleriene ale tuturor
componentelor în C.
Putem parcurge ciclul C cu o coadă, de la stânga la dreapta. În acest caz este important să îl inserăm pe C′ imediat
după poziția curentă (nu înainte), ca să ne asigurăm că și nodurile din C′ sunt analizate.
Pentru o implementare considerabil mai scurtă (deși mai greu de înțeles), putem parcurge ciclul C în ordine
inversă, folosind o stivă. Această implementare are avantajul că nu mai trebuie să inserăm sub-ciclurile găsite --
stiva face aceasta pentru noi.
void euler(int u) {
Stack S = { u };
while (!S.empty()) {
u ← S.top();
if (u are muchii netraversate) {
v ← vecin al lui u;
șterge (u,v) din listele de adiacență ale lui u (și v, dacă G este neorientat);
S.push(v);
} else {
S.pop();
print u;
algopedia.ro/wiki/index.php/Clasele_11-12_lecția_20_-_25_feb_2015 2/4
1/30/2021 Clasele 11-12 lecția 20 - 25 feb 2015 - Algopedia
}
}
}
Așa cum este comun în recursivitate, privim problema la nivel local pentru a o rezolva la nivel global. Dacă nodul
u nu mai are muchii neexplorate, îl tipărim și revenim în nodul părinte. Dacă nodul u mai are muchii, alegem una
dintre ele la întâmplare, (u, v) și îl punem pe v pe stivă pentru a găsi un nou ciclu în acea direcție.
Detalii de implementare
Stivă proprie
Întrucât ciclul găsit poate avea lungime m, nu ne putem baza pe stiva recursivității. Trebuie să ne implementăm
propria stivă.
Graf neorientat
Dacă graful este neorientat, știm deja că stocarea prin liste de adiacență dublează memoria necesară, deoarece
muchia (u, v) trebuie stocată atât în lista de adiacență a lui u, cât și a lui v.
La parcurgerile DFS sau BFS, acest lucru nu ne deranjează, căci folosim un vector de variabile booleene care să
evite revizitarea nodurilor. Dar când căutăm un ciclu eulerian, dorim să revizităm noduri! Din această cauză,
trebuie să gestionăm cazul în care muchia (u, v) a fost traversată dinspre u spre v și trebuie să interzicem
traversarea ei și dinspre v spre u. Iată două abordări.
Infoarena propune să parcurgem naiv lista de adiacență a lui v, să-l găsim pe u și să ștergem înregistrarea
respectivă. Această abordare poate fi acceptabilă în grafuri rare. De exemplu, când n = 100.000 și m = 500.000, și
presupunând că graful este relativ uniform, atunci fiecare nod va avea, la început, 10 vecini în medie și tot mai
puțini pe măsură ce algoritmul elimină muchii. Dar dacă graful are un subgraf foarte dens sau dacă, de exemplu, n
= 1.001 și m = 500.000, atunci fiecare nod va avea 1.000 de vecini în medie. Complexitatea algoritmului devine
.
O implementare mai curată va facilita găsirea în O(1) a muchiei (v, u) dându-se muchia (u, v). De exemplu, putem
ține pointeri între cele două muchii. Pentru invalidarea muchiei (v, u), o putem șterge direct, dacă stocăm listele de
adiacență ca liste dublu înlănțuite, sau îi putem da lui u o valoare specială (0, -1 etc.).
Punctul de pornire
La limită, definiția ciclului eulerian nu exclude posibilitatea unor noduri de grad 0. Trebuie să ținem minte să
începem traversarea dintr-un nod cu grad nenul. Acesta poate fi, de exemplu, primul capăt al primei muchii citite.
Când graful admite un ciclu sau o cale euleriană, acela este chiar răspunsul. Ce facem când graful nu este eulerian?
Discuție.
Probleme
algopedia.ro/wiki/index.php/Clasele_11-12_lecția_20_-_25_feb_2015 3/4
1/30/2021 Clasele 11-12 lecția 20 - 25 feb 2015 - Algopedia
Temă
Tema 17 seniori (http://varena.ro/runda/tema17-seniori-2014-2015)
algopedia.ro/wiki/index.php/Clasele_11-12_lecția_20_-_25_feb_2015 4/4