Costruiamo un grafo 0 - 1, assegnando agli archi esistenti il peso , e ai loro archi inversi il peso . Successivamente eseguiamo una ricerca in ampiezza. La lunghezza del cammino più breve dal vertice al vertice sarà uguale al numero minimo di archi che devono essere invertiti.
Esempio
Il grafo riportato nell'esempio si presenta come segue:
Implementazione dell'algoritmo
Dichiariamo una costante infinito.
#define INF 0x3F3F3F3FDichiariamo l'array delle distanze minime e la lista di adiacenza del grafo . Per ogni arco, insieme al vertice adiacente, memorizziamo il peso dell'arco ( o ).
vector<int> dist;
vector<vector<pair<int, int> > > g;La funzione bfs implementa la ricerca in ampiezza a partire dal vertice .
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;A seconda del peso dell'arco , aggiungiamo il vertice alla fine o all'inizio della coda.
if (w == 1)
q.push_back(to);
else
q.push_front(to);
}
}
}
}Parte principale del programma. Leggiamo i dati in ingresso.
scanf("%d %d", &n, &m);
g.resize(n + 1);
for (i = 0; i < m; i++)
{
scanf("%d %d", &a, &b);All'arco orientato a → b assegniamo il peso , all'arco inverso assegniamo il peso .
g[a].push_back({ b, 0 });
g[b].push_back({ a, 1 });
}Eseguiamo la ricerca in ampiezza a partire dal vertice .
bfs(1);Stampiamo la risposta — la distanza minima fino al vertice .
if (dist[n] == INF)
printf("-1\n");
else
printf("%d\n", dist[n]);