Побудуємо 0 - 1 граф, присвоївши наявним ребрам вагу , а їхнім зворотним ребрам — вагу . Потім запустимо пошук в ширину. Довжина найкоротшого шляху з вершини у вершину буде дорівнювати мінімальній кількості ребер, які потрібно обернути.
Приклад
Граф, наведений у прикладі, виглядає наступним чином:
Реалізація алгоритму
Оголосимо константу нескінченність.
#define INF 0x3F3F3F3FОголосимо масив найкоротших відстаней та список суміжності графа . Для кожного ребра разом із суміжною вершиною зберігаємо вагу ребра ( або ).
vector\<int\> dist;
vector\<vector\<pair\<int, int\> \> \> g;Функція bfs реалізує пошук в ширину з вершини .
void bfs(int start)
{
dist = vector\<int\>(n + 1, INF);
dist[start] = 0;
deque\<int\> q;
q.push_back(start);
while (!q.empty())
{
int v = q.front(); q.pop_front();
for (auto edge : g[v])
{
int to = edge.first;
int w = edge.second;
if (dist[to] \> dist[v] + w)
{
dist[to] = dist[v] + w;Залежно від ваги ребра додаємо вершину в кінець або в початок черги.
if (w == 1)
q.push_back(to);
else
q.push_front(to);
}
}
}
}Основна частина програми. Читаємо вхідні дані.
scanf("%d %d", &n, &m);
g.resize(n + 1);
for (i = 0; i \< m; i++)
{
scanf("%d %d", &a, &b);Орієнтованому ребру a → b присвоюємо вагу , зворотному ребру присвоюємо вагу .
g[a].push_back({ b, 0 });
g[b].push_back({ a, 1 });
}Запускаємо пошук в ширину з вершини .
bfs(1);Виводимо відповідь — найкоротшу відстань до вершини .
if (dist[n] == INF)
printf("-1\n");
else
printf("%d\n", dist[n]);