Количество путей между двумя узлами в группе обеспечения доступности баз данных
Я хочу найти количество путей между двумя узлами в DAG. O(V^2) и O(V+E) являются приемлемыми.
O(V+E) напоминает мне как-то использовать BFS или DFS, но я не знаю как. Может кто-нибудь помочь?
3 ответа
Выполните топологическую сортировку DAG, затем отсканируйте вершины от цели назад к источнику. Для каждой вершины v
, вести подсчет количества путей от v
к цели. Когда вы добираетесь до источника, значение этого количества является ответом. То есть O(V+E)
,
Число различных путей от узла u до v является суммой различных путей от узлов x до v, где x является прямым потомком u.
Сохраните количество путей к целевому узлу v для каждого узла (временное значение равно 0), перейдите от v (здесь значение равно 1), используя противоположную ориентацию, и пересчитайте это значение для каждого узла (суммируйте значение всех потомков), пока не достигнете и.
Если вы обрабатываете узлы в топологическом порядке (опять противоположная ориентация), вам гарантируется, что все прямые потомки уже вычислены, когда вы посещаете данный узел.
Надеюсь, поможет.
Этот вопрос задавался в другом месте на SO, но нигде не упоминалось более простое решение с использованием DFS + DP; все решения, кажется, используют топологическую сортировку. Более простое решение выглядит так (пути от s до t ):
Добавьте поле в представление вершины для хранения целочисленного счетчика. Первоначально установите количество вершин t равным 1, а количество других вершин равным 0. Запустите DFS с вершиной s в качестве начальной. Когда t обнаружен, он должен быть немедленно помечен как завершенный (BLACK), без дальнейшей обработки, начиная с него. Впоследствии, каждый раз, когда DFS заканчивает вершину v , установите счетчик v равным сумме счетчиков всех вершин, смежных с v. Когда DFS завершит работу с вершиной s , остановится и вернет счетчик, вычисленный для s . Временная сложность этого решения равна O(V+E).
Псевдокод:
simple_path (s, t)
if (s == t)
return 1
else if (path_count != NULL)
return path_count
else
path_count = 0
for each node w ϵ adj[s]
do path_count = path_count + simple_path(w, t)
end
return path_count
end