Clasa a XI-a · Grafuri orientate și drumuri minimeRead in English
Drumuri minime între toate perechile de noduri (Roy-Floyd) în C++
În engleză: Shortest paths between all pairs of nodes (Roy-Floyd)
Ideea
Fiecare arc (x, y) are un cost c ≥ 0. Matricea costurilor d pornește cu d[i][i] = 0, d[x][y] = costul arcului și „infinit” unde nu există arc. Pentru fiecare nod intermediar k (bucla exterioară) încercăm să scurtăm drumul de la i la j trecând prin k: dacă d[i][k] + d[k][j] < d[i][j], îl actualizăm. La final d[i][j] este costul minim al unui drum de la i la j; INF înseamnă că nu există drum. Dacă între două noduri apar mai multe arce, se păstrează cel mai ieftin.
Descrierea în engleză
Every arc (x, y) has a cost c ≥ 0. The cost matrix d starts with d[i][i] = 0, d[x][y] = the arc's cost and 'infinity' where there is no arc. For every intermediate node k (the outer loop) we try to shorten the path from i to j by going through k: if d[i][k] + d[k][j] < d[i][j], we update it. At the end d[i][j] is the minimum cost of a path from i to j; INF means there is no path. If several arcs join two nodes, the cheapest one is kept.
- Complexitate
- O(n³)
- Clasa
- Clasa a XI-a (Grade 11)
Exemple
Intrare
4 6 1 2 3 1 3 8 2 3 2 3 4 1 4 1 4 2 4 7
Ieșire așteptată
0 3 5 6 7 0 2 3 5 8 0 1 4 7 9 0
Intrare
3 1 1 2 5
Ieșire așteptată
0 5 INF INF 0 INF INF INF 0
Codul C++
Codul complet, cu comentarii în română. Îl poți modifica liber și îl poți reseta oricând.
/*
* Titlu: Drumuri minime între toate perechile de noduri (Roy-Floyd)
* Clasa: 11
* Capitol: Grafuri orientate și drumuri minime
* Descriere: Fiecare arc (x, y) are un cost c ≥ 0. Matricea costurilor d pornește cu
* d[i][i] = 0, d[x][y] = costul arcului și „infinit” unde nu există arc. Pentru
* fiecare nod intermediar k (bucla exterioară) încercăm să scurtăm drumul de la
* i la j trecând prin k: dacă d[i][k] + d[k][j] < d[i][j], îl actualizăm. La final
* d[i][j] este costul minim al unui drum de la i la j; INF înseamnă că nu există
* drum. Dacă între două noduri apar mai multe arce, se păstrează cel mai ieftin.
* Complexitate: O(n³)
*
* Exemplu
* Intrare:
* 4 6
* 1 2 3
* 1 3 8
* 2 3 2
* 3 4 1
* 4 1 4
* 2 4 7
* Ieșire:
* 0 3 5 6
* 7 0 2 3
* 5 8 0 1
* 4 7 9 0
*
* Exemplu
* Intrare:
* 3 1
* 1 2 5
* Ieșire:
* 0 5 INF
* INF 0 INF
* INF INF 0
*/
#include <iostream>
using namespace std;
const int INF = 1000000000;
int d[105][105];
int main()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
d[i][j] = (i == j ? 0 : INF);
}
}
for (int k = 1; k <= m; k++)
{
int x, y, c;
cin >> x >> y >> c;
if (c < d[x][y])
{
d[x][y] = c;
}
}
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][k] + d[k][j] < d[i][j])
{
d[i][j] = d[i][k] + d[k][j];
}
}
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (d[i][j] == INF)
{
cout << "INF ";
}
else
{
cout << d[i][j] << ' ';
}
}
cout << '\n';
}
return 0;
}
Rulează pe un g++ adevărat (C++17, -O2) prin Compiler Explorer. Programele trebuie să se termine repede: există o limită de timp.