Didaxis
lecție · Informatică

Algoritmul Roy–Floyd

Drumuri minime între toate perechile de vârfuri.

Se face în:
Clasa a XI-a
Actualizat la: 30 octombrie 2026
1pe scurtstratul 1 din 2 · rezumatul lecției

Pe scurt

Algoritmul Roy–Floyd calculează costurile minime între toate perechile de vârfuri. Pornește de la costurile arcelor directe și verifică dacă trecerea printr-un vârf intermediar îmbunătățește un drum. Pentru 1→2 cu cost 4, 2→3 cu cost 3 și 1→3 cu cost 10, trecerea prin 2 reduce costul 1→3 la 7.

Desen la lecția „Algoritmul Roy–Floyd”
2în detaliustratul 2 din 2 · pentru clasă și Bacalaureat

În detaliu

Algoritmul Roy–Floyd calculează costurile minime între toate perechile de vârfuri ale unui graf orientat sau neorientat ponderat, fără cicluri de cost negativ. Matricea d conține inițial costul arcului direct (0 pe diagonală, o valoare convențională INF dacă arcul lipsește). Pentru fiecare vârf intermediar k, de la 1 la , se verifică pentru toate perechile dacă drumul prin k este mai scurt decât cel cunoscut. Cele trei cicluri imbricate dau timpul și memoria . Ordinea ciclurilor contează: ciclul după k trebuie să fie cel exterior. Testul d[i][k]!=INF && d[k][j]!=INF împiedică adunarea unor valori infinite.

Exemplul 1 — trei vârfuri. Arcele sunt cu 4, cu 3 și cu 10:

#include <iostream>
using namespace std;
int main() {
    const int INF = 1000000, n = 3;
    int d[4][4];
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j) d[i][j] = (i == j ? 0 : INF);
    d[1][2] = 4; d[2][3] = 3; d[1][3] = 10;
    for (int k = 1; k <= n; ++k)
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= n; ++j)
                if (d[i][k] != INF && d[k][j] != INF && d[i][j] > d[i][k] + d[k][j])
                    d[i][j] = d[i][k] + d[k][j];
    cout << d[1][3];
}

Se afișează 7. După folosirea vârfului 2 ca intermediar, d[1][3] devine , mai mic decât arcul direct de cost 10. Valorile d[2][1], d[3][1] și d[3][2] rămân INF, deoarece nu există drum în sens invers.

Exemplul 2 — reconstituirea drumului. Se păstrează un tablou interm[i][j]: când costul de la i la j se îmbunătățește prin k, se memorează k. Procedura drum(i,j) desparte recursiv drumul în i→k și k→j; dacă nu există intermediar, afișează capătul j, adică arcul direct. Graful are arcele cu 3, cu 1, cu 2 și cu 10:

#include <iostream>
using namespace std;
const int INF = 1000000, n = 4;
int d[5][5], interm[5][5];
void drum(int i, int j) {
    int k = interm[i][j];
    if (k == 0) { cout << j << " "; return; }
    drum(i, k);
    drum(k, j);
}
int main() {
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j) d[i][j] = (i == j ? 0 : INF);
    d[1][2] = 3; d[2][3] = 1; d[3][4] = 2; d[1][4] = 10;
    for (int k = 1; k <= n; ++k)
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= n; ++j)
                if (d[i][k] != INF && d[k][j] != INF && d[i][j] > d[i][k] + d[k][j]) {
                    d[i][j] = d[i][k] + d[k][j];
                    interm[i][j] = k;
                }
    cout << d[1][4] << ": 1 ";
    drum(1, 4);
}

Se afișează 6: 1 2 3 4. Pentru k=2 se obține d[1][3]=4 cu interm[1][3]=2, iar d[2][4] rămâne infinit. Pentru k=3 se obțin d[1][4]=4+2=6 cu interm[1][4]=3, în locul arcului direct de cost 10, și d[2][4]=3. Procedura drum(1,4) apelează drum(1,3), care apelează drum(1,2) și drum(2,3), apoi drum(3,4). Drumul minim este .

Exemplul 3 — în formatul examenului. Graful orientat are arcele cu 2, cu 2, cu 1 și cu 7. După rularea algoritmului Roy–Floyd, care este valoarea d[2][1]?

  • a) 1
  • b) 3
  • c) 4
  • d) infinit

Răspunsul corect este b). Nu există arcul , dar există drumul cu costul . Varianta a) este costul arcului . Varianta c) este d[1][3], adică prin vârful 2. Varianta d) ar fi corectă numai dacă nu ar exista niciun drum de la 2 la 1.

Urmărirea matricei din exemplul 2. Notăm INF cu ∞. Inițial liniile sunt 0 3 ∞ 10, ∞ 0 1 ∞, ∞ ∞ 0 2 și ∞ ∞ ∞ 0. Pentru k=1 nu se schimbă nimic, pentru că în vârful 1 nu intră niciun arc. Pentru k=2 se schimbă o singură valoare: d[1][3] devine . Pentru k=3 se schimbă două: d[1][4] devine , iar d[2][4] devine . Pentru k=4 nu se mai îmbunătățește nimic, pentru că din vârful 4 nu pleacă niciun arc. Matricea finală are liniile 0 3 4 6, ∞ 0 1 3, ∞ ∞ 0 2 și ∞ ∞ ∞ 0.

Cazul-limită — ciclul de cost negativ. Dacă există arcele cu cost 1 și cu cost , drumul costă . Pentru k=1, valoarea d[2][2] devine , adică o valoare negativă pe diagonală, deși un vârf ajunge în el însuși cu cost 0. Acest semn arată că graful are un ciclu de cost negativ, iar costurile minime nu mai sunt definite, pentru că fiecare parcurgere a ciclului scade din nou costul. De aceea algoritmul se aplică doar grafurilor fără astfel de cicluri.

Greșeli frecvente

  • Greșit: metoda calculează doar drumuri dintr-o singură sursă.
    Corect: tratează toate perechile.
  • Greșit: un drum inexistent are cost numeric zero.
    Corect: este reprezentat separat, de obicei printr-o valoare infinită convențională.
  • Greșit: valoarea directă 10 rămâne minimă.
    Corect: drumul prin 2 costă 7.
în contul tăuPremium

Testează-te pe această lecție

Lecția o citești aici, fără cont. Testele pe lecții și capitole sunt în cont, cu grile originale Didaxis și explicația fiecăreia: gratuit 10 grile pe zi, fără limită cu Premium, 49 de lei pe lună pentru fiecare copil.

Înainte și după

Surse și referințe

Redactare proprie, conform programei:

  • OMECI 5099/2009, anexa 5, Informatică, p. 4–5, clasa XI intensiv; rocnee.eu

Documente consultate

  • Programa școlară de informatică intensiv, clasa a XI-a (OMECI 5099/2009, anexa 5), CNCE, p. 4–5; rocnee.eu
  • OpenDSA, „All-Pairs Shortest Paths”, opendsa.cs.vt.edu/ODSA/Books/lc/cs383/fall-2018/OpenDSA_Content/html/Floyd.html

Desene: Redactare proprie (desen original)

lecțiile sunt gratuite

Ai citit lecția. Acum verifică-te.