Дан ориентированный
невзвешенный граф. Найти в нем вершину, кратчайшее расстояние от которой до
заданной максимально, и вывести это расстояние.
Вход.
В первой строке содержится три натуральных числа n, m и s (1 ≤ s ≤ n ≤ 5000, 1 ≤ m ≤ 20000) – количество вершин и рёбер в графе и номер заданной вершины соответственно. Далее в m строках перечислены рёбра графа. Каждое ребро задаётся парой чисел –
номерами начальной и конечной вершин соответственно.
Выход.
Выведите искомое кратчайшее расстояние.
Пример входа 1 |
Пример выхода 1 |
3 5 3 1 2 2 1 3 1 2 3 3 3 |
2 |
|
|
Пример входа 2 |
Пример выхода 2 |
5 4 5 1 2 2 3 3 4 4 5 |
4 |
поиск в
ширину
Анализ алгоритма
Построим
обратный ориентированный граф – ориентируем каждое ребро в противоположную
сторону. При помощи поиска в ширину найдем кратчайшие расстояния от вершины s. Вершина v, для которой dist[v] максимально, будет искомой. В задаче требуется вывести
значение dist[v].
Пример
Приведенные в
примере графы имеют вид (возле графа слева приведен инвертированный справа
граф):
Реализация алгоритма
Объявим матрицу смежности g и массив кратчайших расстояний dist.
#define MAX 5001
int dist[MAX], g[MAX][MAX];
Поиск в ширину из вершины start.
void bfs(int start)
{
Инициализируем массив кратчайших расстояний.
memset(dist, -1, sizeof(dist));
dist[start] = 0;
Объявляем очередь. Заносим в очередь начальную вершину start.
queue<int> q;
q.push(start);
while (!q.empty())
{
int v = q.front(); q.pop();
for (int to = 1; to <= n; to++)
{
if (g[v][to] == 1 && dist[to] ==
-1)
{
q.push(to);
dist[to] = dist[v] + 1;
}
}
}
}
Основная часть программы. Читаем входные данные.
scanf("%d %d %d", &n, &m, &s);
for (i = 0; i < m; i++)
{
scanf("%d %d", &u,
&v);
Строим граф. Для каждого входного ориентированного ребра u → v занесем в граф обратое v → u.
g[v][u] = 1;
}
Запускаем поиск в ширину из вершины s.
bfs(s);
Находим вершину i с максимальным
расстоянием dist[i].
res = 0;
for (i = 1; i <= n; i++)
if (dist[i] >
res) res = dist[i];
Выводим искомое расстояние.
printf("%d\n", res);