Chef has started Home Delivery scheme in one of his
restaurants. As the scheme is new, Chef appoints only one employee to deliver
food to various locations. The delivery boy who has been appointed is an
absent-minded chap. He always forgets to fill fuel in his delivery scooter. So
what he does is that whenever Chef sends him for delivery, he goes to the gas
station from the restaurant first. He gets his tank filled and then he heads
towards his destination. He will do this every single time irrespective of
the destination. The delivery boy tries his best to be on time. And to do this,
he will choose those paths (from
restaurant to gas station AND gas station to destinaion) which cost him
the least amount of time. Your task is to tell the Chef how much time
can the delivery boy save if he had enough fuel in his scooter i.e. if he went
to the destination directly without stopping for fuel (taking the path which
costs him least amount of time).
The city has n streets numbered from 0 to n – 1. The restaurant is on street number s, the gas station is on street number g and the food has to be delivered to street d. Note that s, g and d need not be
distinct.
Input. First line contains a single integer n (1 ≤
n ≤ 250). Then follows an n * n matrix t which is represented in n lines with n space separated integers on each line.
t[i][j] (0 ≤ t[i][j] ≤ 105) denotes the time taken to move from the i-th street
to j-th street.
Obviously,
t[i][i] = 0.
Next line contains a single integer m (1 ≤
m ≤ 104), the number of scenarios. The following m lines contain 3 space separated integers s, g and d (0 ≤
s, g, d ≤ n – 1).
Output. For each of the m scenarios, output the time taken by the delivery boy
to deliver the food and the time he could have saved if he went directly
from s to d. Both
these values must be on the same line separated by a
single space.
Sample input |
Sample output |
4 0
2 1 3 1
0 4 5 3
1 0 3 1
1 1 0 4 0
2 1 0
2 2 3
1 2 3
0 1 |
2
0 1
0 3
2 3
2 |
графы – алгоритм Флойда-Уоршела
Задан
взвешенный граф из n вершин. Необходимо ответить на большое число следующих
запросов: найдите величину кратчайшего пути из s в d, если при этом следует посетить g. Следует также выяснить, на сколько
этот путь будет длиннее кратчайшего пути из s в d, если двигаться напрямую.
Запустим
на графе gr алгоритм
Флойда – Уоршела для поиска кратчайших путей между всеми парами вершин. Тогда длина кратчайшего пути из s в d с посещением g составит gr[s][g] + gr[g][d].
Длина непосредственно кратчайшего пути из s в d равна gr[s][d].
Реализация алгоритма
#include <stdio.h>
#include <string.h>
#define MAX 251
int n, i, j, q, s, g, d;
int gr[MAX][MAX];
void floyd(void)
{
int i, j, k;
for (k = 0; k < n; k++)
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (gr[i][k] + gr[k][j] < gr[i][j])
gr[i][j] =
gr[i][k] + gr[k][j];
}
int main(void)
{
scanf("%d", &n);
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
scanf("%d", &gr[i][j]);
floyd();
scanf("%d", &q);
while (q--)
{
scanf("%d %d %d", &s, &g, &d);
int t1 = gr[s][g] + gr[g][d];
int t2 = gr[s][d];
printf("%d %d\n", t1, t1 - t2);
}
return 0;
}