Вы можете найти все пути, используя DFS, как описано Владом. Чтобы найти, какие узлы появляются в каждом пути, вы можете просто сохранить массив логических элементов, который говорит, что каждый узел появился на каждом пути до сих пор. Когда ваш DFS найдет путь, пройдите через каждую вершину не в пути и установите для соответствующего значения массива значение false. Когда вы закончите, только вершины со значениями true будут теми, которые появляются на каждом пути.
псевдокод:
int source;
int sink;
int nVerts;
bool inAllPaths[nVerts]; // init to all true
bool visited[nVerts]; // init to all false
stack<int> path; // init empty
bool dfs(int u)
if (visited[u])
return;
if (u == sink)
for i = 0 to nVerts-1
if !stack.contains(i)
inAllPaths[i] = false;
return true;
else
visited[u] = true;
stack.push(u);
foreach edge (u, v)
dfs(v);
stack.pop();
visited[u] = false;
return false;
main()
dfs(source);
// inAllPaths contains true at vertices that exist in all paths
// from source to sink.
Однако этот алгоритм не очень эффективный. Например, в полном графике n вершин (все вершины имеют ребра для всех остальных) число путей будет n! (n факториал).
Лучшим алгоритмом было бы проверить наличие в каждом пути каждой вершины отдельно. Для каждой вершины попробуйте найти путь от источника к раковине, не переходя к этой вершине. Если вы не можете найти его, это потому, что вершина появляется на каждом пути.
псевдокод:
// Using the same initialisation as above, but with a slight modification
// to dfs: change the foreach loop to
foreach edge (u, v)
if (dfs(v))
return true; // exit as soon as we find a path
main()
for i = 0 to nVerts-1
set all visited to false;
if (inAllPaths[i])
visited[i] = true;
if (dfs(source))
inAllPaths[i] = false;
visited[i] = false;
К сожалению, это все еще имеет экспоненциальный худший случай при поиске пути. Вы можете исправить это, изменив поиск на поиск по ширине. Если я не ошибаюсь, это должно дать вам производительность O (VE).
Домашнее задание? что ты уже испробовал? – user85509
не будет бесконечного числа путей, если граф цикличен? – jalf
@jalf, я тоже так думал, но в Википедии есть некоторые разногласия. «Путь без повторяющихся вершин называется простым путем, а цикл без повторных вершин или ребер, кроме необходимого повторения начальной и конечной вершины, является простым циклом. В современной теории графов чаще всего« простой »подразумевается , т. е. «цикл» означает «простой цикл», а «путь» означает «простой путь», но это соглашение не всегда наблюдается, особенно в прикладной теории графов ». –