Çəki verilmiş qrafda Deykstra alqoritmi ilə müəyyən edilir:
nöqtəsindən nöqtəsinə olan ən qısa məsafə dist_{ab};
nöqtəsindən nöqtəsinə olan ən qısa məsafə dist_{ac};
nöqtəsindən nöqtəsinə olan ən qısa məsafə dist_{bc};
Sergeyi götürmədən İvan dist_{ac} məsafəsini gedir.
Sergeyi götürərək isə dist_{ab} + dist_{bc} uzunluğunda yol gedir.
Problemin cavabı bərabərdir
Bu, Sergeyi götürməyin nəticəsində səfərin daha bahalı olduğu məbləğdir.
Misal
Yol qrafı aşağıdakı şəkildədir:
Ən qısa məsafələri hesablayırıq:
-dan -yə olan ən qısa yol dist_{ab} -ə bərabərdir;
-dan -yə olan ən qısa yol dist_{ac} -ə bərabərdir;
-dən -yə olan ən qısa yol dist_{bc} -ə bərabərdir;
İvanın Sergeyi götürmədən getdiyi məsafə: dist_{ac} = 7.5.
Sergeyi götürməklə gedilən məsafə: dist_{ab} + dist_{bc} = 5.5 + 8 = 13.5.
Beləliklə, problemin cavabı bərabərdir:
Alqoritmin reallaşdırılması
Qraf çəki verilmiş qonşuluq matrisi şəklində saxlanılır. Ən qısa məsafələri saxlamaq üçün və məsafəsi artıq hesablanmış zirvələri saxlamaq üçün massivini elan edirik.
#define MAX 110
double g[MAX][MAX], dist[MAX];
int used[MAX];Dijkstra funksiyası zirvəsindən zirvəsinə ən qısa yolun uzunluğunu qaytarır.
double Dijkstra(int s, int f)
{
memset(used, 0, sizeof(used));
for (i = 1; i <= n; i++) dist[i] = 1e18;
dist[s] = 0;
for (i = 1; i < n; i++)
{
double min = 1e18;
int w = -1;
for (j = 1; j <= n; j++)
if (used[j] == 0 && dist[j] < min) { min = dist[j]; w = j; }
if (min == 1e18) break;
for (j = 1; j <= n; j++)
if (used[j] == 0) dist[j] = minimum(dist[j], dist[w] + g[w][j]);
used[w] = 1;
}
return dist[f];
}Proqramın əsas hissəsi. Giriş məlumatlarını oxuyuruq.
scanf("%d %d %d %d %lf", &n, &a, &b, &c, &d);
scanf("%d", &m);
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++) g[i][j] = 1e18;
for (i = 0; i < m; i++)
{
scanf("%d %d %lf", &s, &f, &w);
g[s][f] = g[f][s] = w;
}dist_{ab}, dist_{bc}, dist_{ac} dəyərlərini hesablayırıq.
double d1 = Dijkstra(a, b);
double d2 = Dijkstra(b, c);
double ds = Dijkstra(a, c);Əgər bu dəyərlərdən hansısa biri sonsuzluğa bərabərdirsə, bu, müvafiq marşrutun mövcud olmadığı deməkdir — bu halda çıxış edirik.
if (d1 == 1e18 || d2 == 1e18 || ds == 1e18) printf("-1\n");Əks halda (dist_{ab} + dist_{bc} - dist_{ac}) * d cavabını çıxış edirik.
else printf("%lf\n", (d1 + d2 - ds) * d);